home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''
- Turtle graphics is a popular way for introducing programming to
- kids. It was part of the original Logo programming language developed
- by Wally Feurzig and Seymour Papert in 1966.
-
- Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
- the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
- the direction it is facing, drawing a line as it moves. Give it the
- command turtle.left(25), and it rotates in-place 25 degrees clockwise.
-
- By combining together these and similar commands, intricate shapes and
- pictures can easily be drawn.
-
- ----- turtle.py
-
- This module is an extended reimplementation of turtle.py from the
- Python standard distribution up to Python 2.5. (See: http://www.python.org)
-
- It tries to keep the merits of turtle.py and to be (nearly) 100%
- compatible with it. This means in the first place to enable the
- learning programmer to use all the commands, classes and methods
- interactively when using the module from within IDLE run with
- the -n switch.
-
- Roughly it has the following features added:
-
- - Better animation of the turtle movements, especially of turning the
- turtle. So the turtles can more easily be used as a visual feedback
- instrument by the (beginning) programmer.
-
- - Different turtle shapes, gif-images as turtle shapes, user defined
- and user controllable turtle shapes, among them compound
- (multicolored) shapes. Turtle shapes can be stretched and tilted, which
- makes turtles very versatile geometrical objects.
-
- - Fine control over turtle movement and screen updates via delay(),
- and enhanced tracer() and speed() methods.
-
- - Aliases for the most commonly used commands, like fd for forward etc.,
- following the early Logo traditions. This reduces the boring work of
- typing long sequences of commands, which often occur in a natural way
- when kids try to program fancy pictures on their first encounter with
- turtle graphics.
-
- - Turtles now have an undo()-method with configurable undo-buffer.
-
- - Some simple commands/methods for creating event driven programs
- (mouse-, key-, timer-events). Especially useful for programming games.
-
- - A scrollable Canvas class. The default scrollable Canvas can be
- extended interactively as needed while playing around with the turtle(s).
-
- - A TurtleScreen class with methods controlling background color or
- background image, window and canvas size and other properties of the
- TurtleScreen.
-
- - There is a method, setworldcoordinates(), to install a user defined
- coordinate-system for the TurtleScreen.
-
- - The implementation uses a 2-vector class named Vec2D, derived from tuple.
- This class is public, so it can be imported by the application programmer,
- which makes certain types of computations very natural and compact.
-
- - Appearance of the TurtleScreen and the Turtles at startup/import can be
- configured by means of a turtle.cfg configuration file.
- The default configuration mimics the appearance of the old turtle module.
-
- - If configured appropriately the module reads in docstrings from a docstring
- dictionary in some different language, supplied separately and replaces
- the English ones by those read in. There is a utility function
- write_docstringdict() to write a dictionary with the original (English)
- docstrings to disc, so it can serve as a template for translations.
-
- Behind the scenes there are some features included with possible
- extensions in in mind. These will be commented and documented elsewhere.
-
- '''
- _ver = 'turtle 1.0b1 - for Python 2.6 - 30. 5. 2008, 18:08'
- import Tkinter as TK
- import types
- import math
- import time
- import os
- from os.path import isfile, split, join
- from copy import deepcopy
- from math import *
- _tg_classes = [
- 'ScrolledCanvas',
- 'TurtleScreen',
- 'Screen',
- 'RawTurtle',
- 'Turtle',
- 'RawPen',
- 'Pen',
- 'Shape',
- 'Vec2D']
- _tg_screen_functions = [
- 'addshape',
- 'bgcolor',
- 'bgpic',
- 'bye',
- 'clearscreen',
- 'colormode',
- 'delay',
- 'exitonclick',
- 'getcanvas',
- 'getshapes',
- 'listen',
- 'mode',
- 'onkey',
- 'onscreenclick',
- 'ontimer',
- 'register_shape',
- 'resetscreen',
- 'screensize',
- 'setup',
- 'setworldcoordinates',
- 'title',
- 'tracer',
- 'turtles',
- 'update',
- 'window_height',
- 'window_width']
- _tg_turtle_functions = [
- 'back',
- 'backward',
- 'begin_fill',
- 'begin_poly',
- 'bk',
- 'circle',
- 'clear',
- 'clearstamp',
- 'clearstamps',
- 'clone',
- 'color',
- 'degrees',
- 'distance',
- 'dot',
- 'down',
- 'end_fill',
- 'end_poly',
- 'fd',
- 'fill',
- 'fillcolor',
- 'forward',
- 'get_poly',
- 'getpen',
- 'getscreen',
- 'getturtle',
- 'goto',
- 'heading',
- 'hideturtle',
- 'home',
- 'ht',
- 'isdown',
- 'isvisible',
- 'left',
- 'lt',
- 'onclick',
- 'ondrag',
- 'onrelease',
- 'pd',
- 'pen',
- 'pencolor',
- 'pendown',
- 'pensize',
- 'penup',
- 'pos',
- 'position',
- 'pu',
- 'radians',
- 'right',
- 'reset',
- 'resizemode',
- 'rt',
- 'seth',
- 'setheading',
- 'setpos',
- 'setposition',
- 'settiltangle',
- 'setundobuffer',
- 'setx',
- 'sety',
- 'shape',
- 'shapesize',
- 'showturtle',
- 'speed',
- 'st',
- 'stamp',
- 'tilt',
- 'tiltangle',
- 'towards',
- 'tracer',
- 'turtlesize',
- 'undo',
- 'undobufferentries',
- 'up',
- 'width',
- 'window_height',
- 'window_width',
- 'write',
- 'xcor',
- 'ycor']
- _tg_utilities = [
- 'write_docstringdict',
- 'done',
- 'mainloop']
- _math_functions = [
- 'acos',
- 'asin',
- 'atan',
- 'atan2',
- 'ceil',
- 'cos',
- 'cosh',
- 'e',
- 'exp',
- 'fabs',
- 'floor',
- 'fmod',
- 'frexp',
- 'hypot',
- 'ldexp',
- 'log',
- 'log10',
- 'modf',
- 'pi',
- 'pow',
- 'sin',
- 'sinh',
- 'sqrt',
- 'tan',
- 'tanh']
- __all__ = _tg_classes + _tg_screen_functions + _tg_turtle_functions + _tg_utilities + _math_functions
- _alias_list = [
- 'addshape',
- 'backward',
- 'bk',
- 'fd',
- 'ht',
- 'lt',
- 'pd',
- 'pos',
- 'pu',
- 'rt',
- 'seth',
- 'setpos',
- 'setposition',
- 'st',
- 'turtlesize',
- 'up',
- 'width']
- _CFG = {
- 'width': 0.5,
- 'height': 0.75,
- 'canvwidth': 400,
- 'canvheight': 300,
- 'leftright': None,
- 'topbottom': None,
- 'mode': 'standard',
- 'colormode': 1,
- 'delay': 10,
- 'undobuffersize': 1000,
- 'shape': 'classic',
- 'pencolor': 'black',
- 'fillcolor': 'black',
- 'resizemode': 'noresize',
- 'visible': True,
- 'language': 'english',
- 'exampleturtle': 'turtle',
- 'examplescreen': 'screen',
- 'title': 'Python Turtle Graphics',
- 'using_IDLE': False }
-
- def config_dict(filename):
- '''Convert content of config-file into dictionary.'''
- f = open(filename, 'r')
- cfglines = f.readlines()
- f.close()
- cfgdict = { }
- for line in cfglines:
- line = line.strip()
- if not line or line.startswith('#'):
- continue
-
-
- try:
- (key, value) = line.split('=')
- except:
- print 'Bad line in config-file %s:\n%s' % (filename, line)
- continue
-
- key = key.strip()
- value = value.strip()
- if value in ('True', 'False', 'None', "''", '""'):
- value = eval(value)
- else:
-
- try:
- if '.' in value:
- value = float(value)
- else:
- value = int(value)
- except:
- pass
-
- cfgdict[key] = value
-
- return cfgdict
-
-
- def readconfig(cfgdict):
- """Read config-files, change configuration-dict accordingly.
-
- If there is a turtle.cfg file in the current working directory,
- read it from there. If this contains an importconfig-value,
- say 'myway', construct filename turtle_mayway.cfg else use
- turtle.cfg and read it from the import-directory, where
- turtle.py is located.
- Update configuration dictionary first according to config-file,
- in the import directory, then according to config-file in the
- current working directory.
- If no config-file is found, the default configuration is used.
- """
- default_cfg = 'turtle.cfg'
- cfgdict1 = { }
- cfgdict2 = { }
- if isfile(default_cfg):
- cfgdict1 = config_dict(default_cfg)
-
- if 'importconfig' in cfgdict1:
- default_cfg = 'turtle_%s.cfg' % cfgdict1['importconfig']
-
-
- try:
- (head, tail) = split(__file__)
- cfg_file2 = join(head, default_cfg)
- except:
- cfg_file2 = ''
-
- if isfile(cfg_file2):
- cfgdict2 = config_dict(cfg_file2)
-
- _CFG.update(cfgdict2)
- _CFG.update(cfgdict1)
-
-
- try:
- readconfig(_CFG)
- except:
- print 'No configfile read, reason unknown'
-
-
- class Vec2D(tuple):
- '''A 2 dimensional vector class, used as a helper class
- for implementing turtle graphics.
- May be useful for turtle graphics programs also.
- Derived from tuple, so a vector is a tuple!
-
- Provides (for a, b vectors, k number):
- a+b vector addition
- a-b vector subtraction
- a*b inner product
- k*a and a*k multiplication with scalar
- |a| absolute value of a
- a.rotate(angle) rotation
- '''
-
- def __new__(cls, x, y):
- return tuple.__new__(cls, (x, y))
-
-
- def __add__(self, other):
- return Vec2D(self[0] + other[0], self[1] + other[1])
-
-
- def __mul__(self, other):
- if isinstance(other, Vec2D):
- return self[0] * other[0] + self[1] * other[1]
- return Vec2D(self[0] * other, self[1] * other)
-
-
- def __rmul__(self, other):
- if isinstance(other, int) or isinstance(other, float):
- return Vec2D(self[0] * other, self[1] * other)
-
-
- def __sub__(self, other):
- return Vec2D(self[0] - other[0], self[1] - other[1])
-
-
- def __neg__(self):
- return Vec2D(-self[0], -self[1])
-
-
- def __abs__(self):
- return (self[0] ** 2 + self[1] ** 2) ** 0.5
-
-
- def rotate(self, angle):
- '''rotate self counterclockwise by angle
- '''
- perp = Vec2D(-self[1], self[0])
- angle = angle * math.pi / 180
- c = math.cos(angle)
- s = math.sin(angle)
- return Vec2D(self[0] * c + perp[0] * s, self[1] * c + perp[1] * s)
-
-
- def __getnewargs__(self):
- return (self[0], self[1])
-
-
- def __repr__(self):
- return '(%.2f,%.2f)' % self
-
-
-
- def __methodDict(cls, _dict):
- '''helper function for Scrolled Canvas'''
- baseList = list(cls.__bases__)
- baseList.reverse()
- for _super in baseList:
- __methodDict(_super, _dict)
-
- for key, value in cls.__dict__.items():
- if type(value) == types.FunctionType:
- _dict[key] = value
- continue
-
-
-
- def __methods(cls):
- '''helper function for Scrolled Canvas'''
- _dict = { }
- __methodDict(cls, _dict)
- return _dict.keys()
-
- __stringBody = 'def %(method)s(self, *args, **kw): return ' + 'self.%(attribute)s.%(method)s(*args, **kw)'
-
- def __forwardmethods(fromClass, toClass, toPart, exclude = ()):
- '''Helper functions for Scrolled Canvas, used to forward
- ScrolledCanvas-methods to Tkinter.Canvas class.
- '''
- _dict = { }
- __methodDict(toClass, _dict)
- for ex in _dict.keys():
- if ex[:1] == '_' or ex[-1:] == '_':
- del _dict[ex]
- continue
-
- for ex in exclude:
- if _dict.has_key(ex):
- del _dict[ex]
- continue
-
- for ex in __methods(fromClass):
- if _dict.has_key(ex):
- del _dict[ex]
- continue
-
- for method, func in _dict.items():
- d = {
- 'method': method,
- 'func': func }
- if type(toPart) == types.StringType:
- execString = __stringBody % {
- 'method': method,
- 'attribute': toPart }
-
- exec execString in d
- fromClass.__dict__[method] = d[method]
-
-
-
- class ScrolledCanvas(TK.Frame):
- """Modeled after the scrolled canvas class from Grayons's Tkinter book.
-
- Used as the default canvas, which pops up automatically when
- using turtle graphics functions or the Turtle class.
- """
-
- def __init__(self, master, width = 500, height = 350, canvwidth = 600, canvheight = 500):
- TK.Frame.__init__(self, master, width = width, height = height)
- self._rootwindow = self.winfo_toplevel()
- self.width = width
- self.height = height
- self.canvwidth = canvwidth
- self.canvheight = canvheight
- self.bg = 'white'
- self._canvas = TK.Canvas(master, width = width, height = height, bg = self.bg, relief = TK.SUNKEN, borderwidth = 2)
- self.hscroll = TK.Scrollbar(master, command = self._canvas.xview, orient = TK.HORIZONTAL)
- self.vscroll = TK.Scrollbar(master, command = self._canvas.yview)
- self._canvas.configure(xscrollcommand = self.hscroll.set, yscrollcommand = self.vscroll.set)
- self.rowconfigure(0, weight = 1, minsize = 0)
- self.columnconfigure(0, weight = 1, minsize = 0)
- self._canvas.grid(padx = 1, in_ = self, pady = 1, row = 0, column = 0, rowspan = 1, columnspan = 1, sticky = 'news')
- self.vscroll.grid(padx = 1, in_ = self, pady = 1, row = 0, column = 1, rowspan = 1, columnspan = 1, sticky = 'news')
- self.hscroll.grid(padx = 1, in_ = self, pady = 1, row = 1, column = 0, rowspan = 1, columnspan = 1, sticky = 'news')
- self.reset()
- self._rootwindow.bind('<Configure>', self.onResize)
-
-
- def reset(self, canvwidth = None, canvheight = None, bg = None):
- '''Adjust canvas and scrollbars according to given canvas size.'''
- if canvwidth:
- self.canvwidth = canvwidth
-
- if canvheight:
- self.canvheight = canvheight
-
- if bg:
- self.bg = bg
-
- self._canvas.config(bg = bg, scrollregion = (-(self.canvwidth) // 2, -(self.canvheight) // 2, self.canvwidth // 2, self.canvheight // 2))
- self._canvas.xview_moveto(0.5 * ((self.canvwidth - self.width) + 30) / self.canvwidth)
- self._canvas.yview_moveto(0.5 * ((self.canvheight - self.height) + 30) / self.canvheight)
- self.adjustScrolls()
-
-
- def adjustScrolls(self):
- ''' Adjust scrollbars according to window- and canvas-size.
- '''
- cwidth = self._canvas.winfo_width()
- cheight = self._canvas.winfo_height()
- self._canvas.xview_moveto(0.5 * (self.canvwidth - cwidth) / self.canvwidth)
- self._canvas.yview_moveto(0.5 * (self.canvheight - cheight) / self.canvheight)
- if cwidth < self.canvwidth or cheight < self.canvheight:
- self.hscroll.grid(padx = 1, in_ = self, pady = 1, row = 1, column = 0, rowspan = 1, columnspan = 1, sticky = 'news')
- self.vscroll.grid(padx = 1, in_ = self, pady = 1, row = 0, column = 1, rowspan = 1, columnspan = 1, sticky = 'news')
- else:
- self.hscroll.grid_forget()
- self.vscroll.grid_forget()
-
-
- def onResize(self, event):
- '''self-explanatory'''
- self.adjustScrolls()
-
-
- def bbox(self, *args):
- """ 'forward' method, which canvas itself has inherited...
- """
- return self._canvas.bbox(*args)
-
-
- def cget(self, *args, **kwargs):
- """ 'forward' method, which canvas itself has inherited...
- """
- return self._canvas.cget(*args, **kwargs)
-
-
- def config(self, *args, **kwargs):
- """ 'forward' method, which canvas itself has inherited...
- """
- self._canvas.config(*args, **kwargs)
-
-
- def bind(self, *args, **kwargs):
- """ 'forward' method, which canvas itself has inherited...
- """
- self._canvas.bind(*args, **kwargs)
-
-
- def unbind(self, *args, **kwargs):
- """ 'forward' method, which canvas itself has inherited...
- """
- self._canvas.unbind(*args, **kwargs)
-
-
- def focus_force(self):
- """ 'forward' method, which canvas itself has inherited...
- """
- self._canvas.focus_force()
-
-
- __forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
-
- class _Root(TK.Tk):
- '''Root class for Screen based on Tkinter.'''
-
- def __init__(self):
- TK.Tk.__init__(self)
-
-
- def setupcanvas(self, width, height, cwidth, cheight):
- self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
- self._canvas.pack(expand = 1, fill = 'both')
-
-
- def _getcanvas(self):
- return self._canvas
-
-
- def set_geometry(self, width, height, startx, starty):
- self.geometry('%dx%d%+d%+d' % (width, height, startx, starty))
-
-
- def ondestroy(self, destroy):
- self.wm_protocol('WM_DELETE_WINDOW', destroy)
-
-
- def win_width(self):
- return self.winfo_screenwidth()
-
-
- def win_height(self):
- return self.winfo_screenheight()
-
-
- Canvas = TK.Canvas
-
- class TurtleScreenBase(object):
- '''Provide the basic graphics functionality.
- Interface between Tkinter and turtle.py.
-
- To port turtle.py to some different graphics toolkit
- a corresponding TurtleScreenBase class has to be implemented.
- '''
-
- def _blankimage():
- '''return a blank image object
- '''
- img = TK.PhotoImage(width = 1, height = 1)
- img.blank()
- return img
-
- _blankimage = staticmethod(_blankimage)
-
- def _image(filename):
- '''return an image object containing the
- imagedata from a gif-file named filename.
- '''
- return TK.PhotoImage(file = filename)
-
- _image = staticmethod(_image)
-
- def __init__(self, cv):
- self.cv = cv
- if isinstance(cv, ScrolledCanvas):
- w = self.cv.canvwidth
- h = self.cv.canvheight
- else:
- w = int(self.cv.cget('width'))
- h = int(self.cv.cget('height'))
- self.cv.config(scrollregion = (-w // 2, -h // 2, w // 2, h // 2))
- self.canvwidth = w
- self.canvheight = h
- self.xscale = self.yscale = 1
-
-
- def _createpoly(self):
- '''Create an invisible polygon item on canvas self.cv)
- '''
- return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill = '', outline = '')
-
-
- def _drawpoly(self, polyitem, coordlist, fill = None, outline = None, width = None, top = False):
- """Configure polygonitem polyitem according to provided
- arguments:
- coordlist is sequence of coordinates
- fill is filling color
- outline is outline color
- top is a boolean value, which specifies if polyitem
- will be put on top of the canvas' displaylist so it
- will not be covered by other items.
- """
- cl = []
- for x, y in coordlist:
- cl.append(x * self.xscale)
- cl.append(-y * self.yscale)
-
- self.cv.coords(polyitem, *cl)
- if fill is not None:
- self.cv.itemconfigure(polyitem, fill = fill)
-
- if outline is not None:
- self.cv.itemconfigure(polyitem, outline = outline)
-
- if width is not None:
- self.cv.itemconfigure(polyitem, width = width)
-
- if top:
- self.cv.tag_raise(polyitem)
-
-
-
- def _createline(self):
- '''Create an invisible line item on canvas self.cv)
- '''
- return self.cv.create_line(0, 0, 0, 0, fill = '', width = 2, capstyle = TK.ROUND)
-
-
- def _drawline(self, lineitem, coordlist = None, fill = None, width = None, top = False):
- """Configure lineitem according to provided arguments:
- coordlist is sequence of coordinates
- fill is drawing color
- width is width of drawn line.
- top is a boolean value, which specifies if polyitem
- will be put on top of the canvas' displaylist so it
- will not be covered by other items.
- """
- if coordlist is not None:
- cl = []
- for x, y in coordlist:
- cl.append(x * self.xscale)
- cl.append(-y * self.yscale)
-
- self.cv.coords(lineitem, *cl)
-
- if fill is not None:
- self.cv.itemconfigure(lineitem, fill = fill)
-
- if width is not None:
- self.cv.itemconfigure(lineitem, width = width)
-
- if top:
- self.cv.tag_raise(lineitem)
-
-
-
- def _delete(self, item):
- '''Delete graphics item from canvas.
- If item is"all" delete all graphics items.
- '''
- self.cv.delete(item)
-
-
- def _update(self):
- '''Redraw graphics items on canvas
- '''
- self.cv.update()
-
-
- def _delay(self, delay):
- '''Delay subsequent canvas actions for delay ms.'''
- self.cv.after(delay)
-
-
- def _iscolorstring(self, color):
- '''Check if the string color is a legal Tkinter color string.
- '''
-
- try:
- rgb = self.cv.winfo_rgb(color)
- ok = True
- except TK.TclError:
- ok = False
-
- return ok
-
-
- def _bgcolor(self, color = None):
- """Set canvas' backgroundcolor if color is not None,
- else return backgroundcolor."""
- if color is not None:
- self.cv.config(bg = color)
- self._update()
- else:
- return self.cv.cget('bg')
- return color is not None
-
-
- def _write(self, pos, txt, align, font, pencolor):
- """Write txt at pos in canvas with specified font
- and color.
- Return text item and x-coord of right bottom corner
- of text's bounding box."""
- (x, y) = pos
- x = x * self.xscale
- y = y * self.yscale
- anchor = {
- 'left': 'sw',
- 'center': 's',
- 'right': 'se' }
- item = self.cv.create_text(x - 1, -y, text = txt, anchor = anchor[align], fill = pencolor, font = font)
- (x0, y0, x1, y1) = self.cv.bbox(item)
- self.cv.update()
- return (item, x1 - 1)
-
-
- def _onclick(self, item, fun, num = 1, add = None):
- '''Bind fun to mouse-click event on turtle.
- fun must be a function with two arguments, the coordinates
- of the clicked point on the canvas.
- num, the number of the mouse-button defaults to 1
- '''
- pass
-
-
- def _onrelease(self, item, fun, num = 1, add = None):
- '''Bind fun to mouse-button-release event on turtle.
- fun must be a function with two arguments, the coordinates
- of the point on the canvas where mouse button is released.
- num, the number of the mouse-button defaults to 1
-
- If a turtle is clicked, first _onclick-event will be performed,
- then _onscreensclick-event.
- '''
- pass
-
-
- def _ondrag(self, item, fun, num = 1, add = None):
- '''Bind fun to mouse-move-event (with pressed mouse button) on turtle.
- fun must be a function with two arguments, the coordinates of the
- actual mouse position on the canvas.
- num, the number of the mouse-button defaults to 1
-
- Every sequence of mouse-move-events on a turtle is preceded by a
- mouse-click event on that turtle.
- '''
- pass
-
-
- def _onscreenclick(self, fun, num = 1, add = None):
- '''Bind fun to mouse-click event on canvas.
- fun must be a function with two arguments, the coordinates
- of the clicked point on the canvas.
- num, the number of the mouse-button defaults to 1
-
- If a turtle is clicked, first _onclick-event will be performed,
- then _onscreensclick-event.
- '''
- pass
-
-
- def _onkey(self, fun, key):
- '''Bind fun to key-release event of key.
- Canvas must have focus. See method listen
- '''
- pass
-
-
- def _listen(self):
- '''Set focus on canvas (in order to collect key-events)
- '''
- self.cv.focus_force()
-
-
- def _ontimer(self, fun, t):
- '''Install a timer, which calls fun after t milliseconds.
- '''
- if t == 0:
- self.cv.after_idle(fun)
- else:
- self.cv.after(t, fun)
-
-
- def _createimage(self, image):
- '''Create and return image item on canvas.
- '''
- return self.cv.create_image(0, 0, image = image)
-
-
- def _drawimage(self, item, .2, image):
- '''Configure image item as to draw image object
- at position (x,y) on canvas)
- '''
- (x, y) = .2
- self.cv.coords(item, (x * self.xscale, -y * self.yscale))
- self.cv.itemconfig(item, image = image)
-
-
- def _setbgpic(self, item, image):
- '''Configure image item as to draw image object
- at center of canvas. Set item to the first item
- in the displaylist, so it will be drawn below
- any other item .'''
- self.cv.itemconfig(item, image = image)
- self.cv.tag_lower(item)
-
-
- def _type(self, item):
- """Return 'line' or 'polygon' or 'image' depending on
- type of item.
- """
- return self.cv.type(item)
-
-
- def _pointlist(self, item):
- '''returns list of coordinate-pairs of points of item
- Example (for insiders):
- >>> from turtle import *
- >>> getscreen()._pointlist(getturtle().turtle._item)
- [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
- (9.9999999999999982, 0.0)]
- >>> '''
- cl = self.cv.coords(item)
- pl = [ (cl[i], -cl[i + 1]) for i in range(0, len(cl), 2) ]
- return pl
-
-
- def _setscrollregion(self, srx1, sry1, srx2, sry2):
- self.cv.config(scrollregion = (srx1, sry1, srx2, sry2))
-
-
- def _rescale(self, xscalefactor, yscalefactor):
- items = self.cv.find_all()
- for item in items:
- coordinates = self.cv.coords(item)
- newcoordlist = []
- while coordinates:
- (x, y) = coordinates[:2]
- newcoordlist.append(x * xscalefactor)
- newcoordlist.append(y * yscalefactor)
- coordinates = coordinates[2:]
- self.cv.coords(item, *newcoordlist)
-
-
-
- def _resize(self, canvwidth = None, canvheight = None, bg = None):
- '''Resize the canvas the turtles are drawing on. Does
- not alter the drawing window.
- '''
- if not isinstance(self.cv, ScrolledCanvas):
- return (self.canvwidth, self.canvheight)
- if canvwidth is None and canvheight is None and bg is None:
- return (self.cv.canvwidth, self.cv.canvheight)
- if canvheight is not None:
- self.canvheight = canvheight
-
- self.cv.reset(canvwidth, canvheight, bg)
-
-
- def _window_size(self):
- ''' Return the width and height of the turtle window.
- '''
- width = self.cv.winfo_width()
- if width <= 1:
- width = self.cv['width']
-
- height = self.cv.winfo_height()
- if height <= 1:
- height = self.cv['height']
-
- return (width, height)
-
-
-
- class Terminator(Exception):
- '''Will be raised in TurtleScreen.update, if _RUNNING becomes False.
-
- Thus stops execution of turtle graphics script. Main purpose: use in
- in the Demo-Viewer turtle.Demo.py.
- '''
- pass
-
-
- class TurtleGraphicsError(Exception):
- '''Some TurtleGraphics Error
- '''
- pass
-
-
- class Shape(object):
- '''Data structure modeling shapes.
-
- attribute _type is one of "polygon", "image", "compound"
- attribute _data is - depending on _type a poygon-tuple,
- an image or a list constructed using the addcomponent method.
- '''
-
- def __init__(self, type_, data = None):
- self._type = type_
- if type_ == 'polygon':
- if isinstance(data, list):
- data = tuple(data)
-
- elif type_ == 'image':
- if isinstance(data, str):
- if data.lower().endswith('.gif') and isfile(data):
- data = TurtleScreen._image(data)
-
-
- elif type_ == 'compound':
- data = []
- else:
- raise TurtleGraphicsError('There is no shape type %s' % type_)
- self._data = type_ == 'polygon'
-
-
- def addcomponent(self, poly, fill, outline = None):
- '''Add component to a shape of type compound.
-
- Arguments: poly is a polygon, i. e. a tuple of number pairs.
- fill is the fillcolor of the component,
- outline is the outline color of the component.
-
- call (for a Shapeobject namend s):
- -- s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
-
- Example:
- >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
- >>> s = Shape("compound")
- >>> s.addcomponent(poly, "red", "blue")
- ### .. add more components and then use register_shape()
- '''
- if self._type != 'compound':
- raise TurtleGraphicsError('Cannot add component to %s Shape' % self._type)
- self._type != 'compound'
- if outline is None:
- outline = fill
-
- self._data.append([
- poly,
- fill,
- outline])
-
-
-
- class Tbuffer(object):
- '''Ring buffer used as undobuffer for RawTurtle objects.'''
-
- def __init__(self, bufsize = 10):
- self.bufsize = bufsize
- self.buffer = [
- [
- None]] * bufsize
- self.ptr = -1
- self.cumulate = False
-
-
- def reset(self, bufsize = None):
- if bufsize is None:
- for i in range(self.bufsize):
- self.buffer[i] = [
- None]
-
- else:
- self.bufsize = bufsize
- self.buffer = [
- [
- None]] * bufsize
- self.ptr = -1
-
-
- def push(self, item):
- if self.bufsize > 0:
- if not self.cumulate:
- self.ptr = (self.ptr + 1) % self.bufsize
- self.buffer[self.ptr] = item
- else:
- self.buffer[self.ptr].append(item)
-
-
-
- def pop(self):
- if self.bufsize > 0:
- item = self.buffer[self.ptr]
- if item is None:
- return None
- self.buffer[self.ptr] = [
- None]
- self.ptr = (self.ptr - 1) % self.bufsize
- return item
- self.bufsize > 0
-
-
- def nr_of_items(self):
- return self.bufsize - self.buffer.count([
- None])
-
-
- def __repr__(self):
- return str(self.buffer) + ' ' + str(self.ptr)
-
-
-
- class TurtleScreen(TurtleScreenBase):
- '''Provides screen oriented methods like setbg etc.
-
- Only relies upon the methods of TurtleScreenBase and NOT
- upon components of the underlying graphics toolkit -
- which is Tkinter in this case.
- '''
- _RUNNING = True
-
- def __init__(self, cv, mode = _CFG['mode'], colormode = _CFG['colormode'], delay = _CFG['delay']):
- self._shapes = {
- 'arrow': Shape('polygon', ((-10, 0), (10, 0), (0, 10))),
- 'turtle': Shape('polygon', ((0, 16), (-2, 14), (-1, 10), (-4, 7), (-7, 9), (-9, 8), (-6, 5), (-7, 1), (-5, -3), (-8, -6), (-6, -8), (-4, -5), (0, -7), (4, -5), (6, -8), (8, -6), (5, -3), (7, 1), (6, 5), (9, 8), (7, 9), (4, 7), (1, 10), (2, 14))),
- 'circle': Shape('polygon', ((10, 0), (9.51, 3.09), (8.09, 5.88), (5.88, 8.09), (3.09, 9.51), (0, 10), (-3.09, 9.51), (-5.88, 8.09), (-8.09, 5.88), (-9.51, 3.09), (-10, 0), (-9.51, -3.09), (-8.09, -5.88), (-5.88, -8.09), (-3.09, -9.51), (-0, -10), (3.09, -9.51), (5.88, -8.09), (8.09, -5.88), (9.51, -3.09))),
- 'square': Shape('polygon', ((10, -10), (10, 10), (-10, 10), (-10, -10))),
- 'triangle': Shape('polygon', ((10, -5.77), (0, 11.55), (-10, -5.77))),
- 'classic': Shape('polygon', ((0, 0), (-5, -9), (0, -7), (5, -9))),
- 'blank': Shape('image', self._blankimage()) }
- self._bgpics = {
- 'nopic': '' }
- TurtleScreenBase.__init__(self, cv)
- self._mode = mode
- self._delayvalue = delay
- self._colormode = _CFG['colormode']
- self._keys = []
- self.clear()
-
-
- def clear(self):
- '''Delete all drawings and all turtles from the TurtleScreen.
-
- Reset empty TurtleScreen to its initial state: white background,
- no backgroundimage, no eventbindings and tracing on.
-
- No argument.
-
- Example (for a TurtleScreen instance named screen):
- screen.clear()
-
- Note: this method is not available as function.
- '''
- self._delayvalue = _CFG['delay']
- self._colormode = _CFG['colormode']
- self._delete('all')
- self._bgpic = self._createimage('')
- self._bgpicname = 'nopic'
- self._tracing = 1
- self._updatecounter = 0
- self._turtles = []
- self.bgcolor('white')
- for btn in (1, 2, 3):
- self.onclick(None, btn)
-
- for key in self._keys[:]:
- self.onkey(None, key)
-
- Turtle._pen = None
-
-
- def mode(self, mode = None):
- """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
-
- Optional argument:
- mode -- on of the strings 'standard', 'logo' or 'world'
-
- Mode 'standard' is compatible with turtle.py.
- Mode 'logo' is compatible with most Logo-Turtle-Graphics.
- Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
- this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
- If mode is not given, return the current mode.
-
- Mode Initial turtle heading positive angles
- ------------|-------------------------|-------------------
- 'standard' to the right (east) counterclockwise
- 'logo' upward (north) clockwise
-
- Examples:
- >>> mode('logo') # resets turtle heading to north
- >>> mode()
- 'logo'
- """
- if mode == None:
- return self._mode
- mode = mode.lower()
- if mode not in ('standard', 'logo', 'world'):
- raise TurtleGraphicsError('No turtle-graphics-mode %s' % mode)
- mode not in ('standard', 'logo', 'world')
- self._mode = mode
- self.reset()
-
-
- def setworldcoordinates(self, llx, lly, urx, ury):
- """Set up a user defined coordinate-system.
-
- Arguments:
- llx -- a number, x-coordinate of lower left corner of canvas
- lly -- a number, y-coordinate of lower left corner of canvas
- urx -- a number, x-coordinate of upper right corner of canvas
- ury -- a number, y-coordinate of upper right corner of canvas
-
- Set up user coodinat-system and switch to mode 'world' if necessary.
- This performs a screen.reset. If mode 'world' is already active,
- all drawings are redrawn according to the new coordinates.
-
- But ATTENTION: in user-defined coordinatesystems angles may appear
- distorted. (see Screen.mode())
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
- >>> for _ in range(36):
- left(10)
- forward(0.5)
- """
- if self.mode() != 'world':
- self.mode('world')
-
- xspan = float(urx - llx)
- yspan = float(ury - lly)
- (wx, wy) = self._window_size()
- self.screensize(wx - 20, wy - 20)
- oldxscale = self.xscale
- oldyscale = self.yscale
- self.xscale = self.canvwidth / xspan
- self.yscale = self.canvheight / yspan
- srx1 = llx * self.xscale
- sry1 = -ury * self.yscale
- srx2 = self.canvwidth + srx1
- sry2 = self.canvheight + sry1
- self._setscrollregion(srx1, sry1, srx2, sry2)
- self._rescale(self.xscale / oldxscale, self.yscale / oldyscale)
- self.update()
-
-
- def register_shape(self, name, shape = None):
- '''Adds a turtle shape to TurtleScreen\'s shapelist.
-
- Arguments:
- (1) name is the name of a gif-file and shape is None.
- Installs the corresponding image shape.
- !! Image-shapes DO NOT rotate when turning the turtle,
- !! so they do not display the heading of the turtle!
- (2) name is an arbitrary string and shape is a tuple
- of pairs of coordinates. Installs the corresponding
- polygon shape
- (3) name is an arbitrary string and shape is a
- (compound) Shape object. Installs the corresponding
- compound shape.
- To use a shape, you have to issue the command shape(shapename).
-
- call: register_shape("turtle.gif")
- --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
-
- '''
- if shape is None:
- if name.lower().endswith('.gif'):
- shape = Shape('image', self._image(name))
- else:
- raise TurtleGraphicsError('Bad arguments for register_shape.\n' + 'Use help(register_shape)')
- name.lower().endswith('.gif')
- if isinstance(shape, tuple):
- shape = Shape('polygon', shape)
-
- self._shapes[name] = shape
-
-
- def _colorstr(self, color):
- """Return color string corresponding to args.
-
- Argument may be a string or a tuple of three
- numbers corresponding to actual colormode,
- i.e. in the range 0<=n<=colormode.
-
- If the argument doesn't represent a color,
- an error is raised.
- """
- if len(color) == 1:
- color = color[0]
-
- if isinstance(color, str):
- if self._iscolorstring(color) or color == '':
- return color
- raise TurtleGraphicsError('bad color string: %s' % str(color))
- isinstance(color, str)
-
- try:
- (r, g, b) = color
- except:
- raise TurtleGraphicsError('bad color arguments: %s' % str(color))
-
- if r <= r:
- pass
- elif r <= 255:
- if g <= g:
- pass
- elif g <= 255:
- if b <= b:
- pass
- elif not b <= 255:
- raise TurtleGraphicsError('bad color sequence: %s' % str(color))
-
- return '#%02x%02x%02x' % (r, g, b)
-
-
- def _color(self, cstr):
- if not cstr.startswith('#'):
- return cstr
- if len(cstr) == 7:
- cl = [ int(cstr[i:i + 2], 16) for i in (1, 3, 5) ]
- elif len(cstr) == 4:
- cl = [ 16 * int(cstr[h], 16) for h in cstr[1:] ]
- else:
- raise TurtleGraphicsError('bad colorstring: %s' % cstr)
- return []([ c * self._colormode / 255 for c in cl ])
-
-
- def colormode(self, cmode = None):
- '''Return the colormode or set it to 1.0 or 255.
-
- Optional argument:
- cmode -- one of the values 1.0 or 255
-
- r, g, b values of colortriples have to be in range 0..cmode.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.colormode()
- 1.0
- >>> screen.colormode(255)
- >>> turtle.pencolor(240,160,80)
- '''
- if cmode is None:
- return self._colormode
- if cmode == 1:
- self._colormode = float(cmode)
- elif cmode == 255:
- self._colormode = int(cmode)
-
-
-
- def reset(self):
- '''Reset all Turtles on the Screen to their initial state.
-
- No argument.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.reset()
- '''
- for turtle in self._turtles:
- turtle._setmode(self._mode)
- turtle.reset()
-
-
-
- def turtles(self):
- '''Return the list of turtles on the screen.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.turtles()
- [<turtle.Turtle object at 0x00E11FB0>]
- '''
- return self._turtles
-
-
- def bgcolor(self, *args):
- '''Set or return backgroundcolor of the TurtleScreen.
-
- Arguments (if given): a color string or three numbers
- in the range 0..colormode or a 3-tuple of such numbers.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.bgcolor("orange")
- >>> screen.bgcolor()
- \'orange\'
- >>> screen.bgcolor(0.5,0,0.5)
- >>> screen.bgcolor()
- \'#800080\'
- '''
- if args:
- color = self._colorstr(args)
- else:
- color = None
- color = self._bgcolor(color)
- if color is not None:
- color = self._color(color)
-
- return color
-
-
- def tracer(self, n = None, delay = None):
- '''Turns turtle animation on/off and set delay for update drawings.
-
- Optional arguments:
- n -- nonnegative integer
- delay -- nonnegative integer
-
- If n is given, only each n-th regular screen update is really performed.
- (Can be used to accelerate the drawing of complex graphics.)
- Second arguments sets delay value (see RawTurtle.delay())
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.tracer(8, 25)
- >>> dist = 2
- >>> for i in range(200):
- fd(dist)
- rt(90)
- dist += 2
- '''
- if n is None:
- return self._tracing
- self._tracing = int(n)
- self._updatecounter = 0
- if delay is not None:
- self._delayvalue = int(delay)
-
- if self._tracing:
- self.update()
-
-
-
- def delay(self, delay = None):
- ''' Return or set the drawing delay in milliseconds.
-
- Optional argument:
- delay -- positive integer
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.delay(15)
- >>> screen.delay()
- 15
- '''
- if delay is None:
- return self._delayvalue
- self._delayvalue = int(delay)
-
-
- def _incrementudc(self):
- '''Increment upadate counter.'''
- if not TurtleScreen._RUNNING:
- TurtleScreen._RUNNNING = True
- raise Terminator
- TurtleScreen._RUNNING
-
-
- def update(self):
- '''Perform a TurtleScreen update.
- '''
- tracing = self._tracing
- self._tracing = True
- for t in self.turtles():
- t._update_data()
- t._drawturtle()
-
- self._tracing = tracing
- self._update()
-
-
- def window_width(self):
- ''' Return the width of the turtle window.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.window_width()
- 640
- '''
- return self._window_size()[0]
-
-
- def window_height(self):
- ''' Return the height of the turtle window.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.window_height()
- 480
- '''
- return self._window_size()[1]
-
-
- def getcanvas(self):
- '''Return the Canvas of this TurtleScreen.
-
- No argument.
-
- Example (for a Screen instance named screen):
- >>> cv = screen.getcanvas()
- >>> cv
- <turtle.ScrolledCanvas instance at 0x010742D8>
- '''
- return self.cv
-
-
- def getshapes(self):
- """Return a list of names of all currently available turtle shapes.
-
- No argument.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.getshapes()
- ['arrow', 'blank', 'circle', ... , 'turtle']
- """
- return sorted(self._shapes.keys())
-
-
- def onclick(self, fun, btn = 1, add = None):
- '''Bind fun to mouse-click event on canvas.
-
- Arguments:
- fun -- a function with two arguments, the coordinates of the
- clicked point on the canvas.
- num -- the number of the mouse-button, defaults to 1
-
- Example (for a TurtleScreen instance named screen
- and a Turtle instance named turtle):
-
- >>> screen.onclick(turtle.goto)
-
- ### Subsequently clicking into the TurtleScreen will
- ### make the turtle move to the clicked point.
- >>> screen.onclick(None)
-
- ### event-binding will be removed
- '''
- self._onscreenclick(fun, btn, add)
-
-
- def onkey(self, fun, key):
- '''Bind fun to key-release event of key.
-
- Arguments:
- fun -- a function with no arguments
- key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
-
- In order to be able to register key-events, TurtleScreen
- must have focus. (See method listen.)
-
- Example (for a TurtleScreen instance named screen
- and a Turtle instance named turtle):
-
- >>> def f():
- fd(50)
- lt(60)
-
-
- >>> screen.onkey(f, "Up")
- >>> screen.listen()
-
- ### Subsequently the turtle can be moved by
- ### repeatedly pressing the up-arrow key,
- ### consequently drawing a hexagon
- '''
- if fun == None:
- if key in self._keys:
- self._keys.remove(key)
-
- elif key not in self._keys:
- self._keys.append(key)
-
- self._onkey(fun, key)
-
-
- def listen(self, xdummy = None, ydummy = None):
- '''Set focus on TurtleScreen (in order to collect key-events)
-
- No arguments.
- Dummy arguments are provided in order
- to be able to pass listen to the onclick method.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.listen()
- '''
- self._listen()
-
-
- def ontimer(self, fun, t = 0):
- '''Install a timer, which calls fun after t milliseconds.
-
- Arguments:
- fun -- a function with no arguments.
- t -- a number >= 0
-
- Example (for a TurtleScreen instance named screen):
-
- >>> running = True
- >>> def f():
- if running:
- fd(50)
- lt(60)
- screen.ontimer(f, 250)
-
- >>> f() ### makes the turtle marching around
- >>> running = False
- '''
- self._ontimer(fun, t)
-
-
- def bgpic(self, picname = None):
- '''Set background image or return name of current backgroundimage.
-
- Optional argument:
- picname -- a string, name of a gif-file or "nopic".
-
- If picname is a filename, set the corresponing image as background.
- If picname is "nopic", delete backgroundimage, if present.
- If picname is None, return the filename of the current backgroundimage.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.bgpic()
- \'nopic\'
- >>> screen.bgpic("landscape.gif")
- >>> screen.bgpic()
- \'landscape.gif\'
- '''
- if picname is None:
- return self._bgpicname
- if picname not in self._bgpics:
- self._bgpics[picname] = self._image(picname)
-
- self._setbgpic(self._bgpic, self._bgpics[picname])
- self._bgpicname = picname
-
-
- def screensize(self, canvwidth = None, canvheight = None, bg = None):
- '''Resize the canvas the turtles are drawing on.
-
- Optional arguments:
- canvwidth -- positive integer, new width of canvas in pixels
- canvheight -- positive integer, new height of canvas in pixels
- bg -- colorstring or color-tupel, new backgroundcolor
- If no arguments are given, return current (canvaswidth, canvasheight)
-
- Do not alter the drawing window. To observe hidden parts of
- the canvas use the scrollbars. (Can make visible those parts
- of a drawing, which were outside the canvas before!)
-
- Example (for a Turtle instance named turtle):
- >>> turtle.screensize(2000,1500)
- ### e. g. to search for an erroneously escaped turtle ;-)
- '''
- return self._resize(canvwidth, canvheight, bg)
-
- onscreenclick = onclick
- resetscreen = reset
- clearscreen = clear
- addshape = register_shape
-
-
- class TNavigator(object):
- '''Navigation part of the RawTurtle.
- Implements methods for turtle movement.
- '''
- START_ORIENTATION = {
- 'standard': Vec2D(1, 0),
- 'world': Vec2D(1, 0),
- 'logo': Vec2D(0, 1) }
- DEFAULT_MODE = 'standard'
- DEFAULT_ANGLEOFFSET = 0
- DEFAULT_ANGLEORIENT = 1
-
- def __init__(self, mode = DEFAULT_MODE):
- self._angleOffset = self.DEFAULT_ANGLEOFFSET
- self._angleOrient = self.DEFAULT_ANGLEORIENT
- self._mode = mode
- self.undobuffer = None
- self.degrees()
- self._mode = None
- self._setmode(mode)
- TNavigator.reset(self)
-
-
- def reset(self):
- '''reset turtle to its initial values
-
- Will be overwritten by parent class
- '''
- self._position = Vec2D(0, 0)
- self._orient = TNavigator.START_ORIENTATION[self._mode]
-
-
- def _setmode(self, mode = None):
- """Set turtle-mode to 'standard', 'world' or 'logo'.
- """
- if mode == None:
- return self._mode
- if mode not in ('standard', 'logo', 'world'):
- return None
- self._mode = mode
-
-
- def _setDegreesPerAU(self, fullcircle):
- '''Helper function for degrees() and radians()'''
- self._fullcircle = fullcircle
- self._degreesPerAU = 360 / fullcircle
- if self._mode == 'standard':
- self._angleOffset = 0
- else:
- self._angleOffset = fullcircle / 4
-
-
- def degrees(self, fullcircle = 360):
- """ Set angle measurement units to degrees.
-
- Optional argument:
- fullcircle - a number
-
- Set angle measurement units, i. e. set number
- of 'degrees' for a full circle. Dafault value is
- 360 degrees.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.left(90)
- >>> turtle.heading()
- 90
- >>> turtle.degrees(400.0) # angle measurement in gon
- >>> turtle.heading()
- 100
-
- """
- self._setDegreesPerAU(fullcircle)
-
-
- def radians(self):
- ''' Set the angle measurement units to radians.
-
- No arguments.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.heading()
- 90
- >>> turtle.radians()
- >>> turtle.heading()
- 1.5707963267948966
- '''
- self._setDegreesPerAU(2 * math.pi)
-
-
- def _go(self, distance):
- '''move turtle forward by specified distance'''
- ende = self._position + self._orient * distance
- self._goto(ende)
-
-
- def _rotate(self, angle):
- '''Turn turtle counterclockwise by specified angle if angle > 0.'''
- angle *= self._degreesPerAU
- self._orient = self._orient.rotate(angle)
-
-
- def _goto(self, end):
- '''move turtle to position end.'''
- self._position = end
-
-
- def forward(self, distance):
- '''Move the turtle forward by the specified distance.
-
- Aliases: forward | fd
-
- Argument:
- distance -- a number (integer or float)
-
- Move the turtle forward by the specified distance, in the direction
- the turtle is headed.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.position()
- (0.00, 0.00)
- >>> turtle.forward(25)
- >>> turtle.position()
- (25.00,0.00)
- >>> turtle.forward(-75)
- >>> turtle.position()
- (-50.00,0.00)
- '''
- self._go(distance)
-
-
- def back(self, distance):
- """Move the turtle backward by distance.
-
- Aliases: back | backward | bk
-
- Argument:
- distance -- a number
-
- Move the turtle backward by distance ,opposite to the direction the
- turtle is headed. Do not change the turtle's heading.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.position()
- (0.00, 0.00)
- >>> turtle.backward(30)
- >>> turtle.position()
- (-30.00, 0.00)
- """
- self._go(-distance)
-
-
- def right(self, angle):
- '''Turn turtle right by angle units.
-
- Aliases: right | rt
-
- Argument:
- angle -- a number (integer or float)
-
- Turn turtle right by angle units. (Units are by default degrees,
- but can be set via the degrees() and radians() functions.)
- Angle orientation depends on mode. (See this.)
-
- Example (for a Turtle instance named turtle):
- >>> turtle.heading()
- 22.0
- >>> turtle.right(45)
- >>> turtle.heading()
- 337.0
- '''
- self._rotate(-angle)
-
-
- def left(self, angle):
- '''Turn turtle left by angle units.
-
- Aliases: left | lt
-
- Argument:
- angle -- a number (integer or float)
-
- Turn turtle left by angle units. (Units are by default degrees,
- but can be set via the degrees() and radians() functions.)
- Angle orientation depends on mode. (See this.)
-
- Example (for a Turtle instance named turtle):
- >>> turtle.heading()
- 22.0
- >>> turtle.left(45)
- >>> turtle.heading()
- 67.0
- '''
- self._rotate(angle)
-
-
- def pos(self):
- """Return the turtle's current location (x,y), as a Vec2D-vector.
-
- Aliases: pos | position
-
- No arguments.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.pos()
- (0.00, 240.00)
- """
- return self._position
-
-
- def xcor(self):
- """ Return the turtle's x coordinate.
-
- No arguments.
-
- Example (for a Turtle instance named turtle):
- >>> reset()
- >>> turtle.left(60)
- >>> turtle.forward(100)
- >>> print turtle.xcor()
- 50.0
- """
- return self._position[0]
-
-
- def ycor(self):
- """ Return the turtle's y coordinate
- ---
- No arguments.
-
- Example (for a Turtle instance named turtle):
- >>> reset()
- >>> turtle.left(60)
- >>> turtle.forward(100)
- >>> print turtle.ycor()
- 86.6025403784
- """
- return self._position[1]
-
-
- def goto(self, x, y = None):
- """Move turtle to an absolute position.
-
- Aliases: setpos | setposition | goto:
-
- Arguments:
- x -- a number or a pair/vector of numbers
- y -- a number None
-
- call: goto(x, y) # two coordinates
- --or: goto((x, y)) # a pair (tuple) of coordinates
- --or: goto(vec) # e.g. as returned by pos()
-
- Move turtle to an absolute position. If the pen is down,
- a line will be drawn. The turtle's orientation does not change.
-
- Example (for a Turtle instance named turtle):
- >>> tp = turtle.pos()
- >>> tp
- (0.00, 0.00)
- >>> turtle.setpos(60,30)
- >>> turtle.pos()
- (60.00,30.00)
- >>> turtle.setpos((20,80))
- >>> turtle.pos()
- (20.00,80.00)
- >>> turtle.setpos(tp)
- >>> turtle.pos()
- (0.00,0.00)
- """
- if y is None:
- self._goto(Vec2D(*x))
- else:
- self._goto(Vec2D(x, y))
-
-
- def home(self):
- '''Move turtle to the origin - coordinates (0,0).
-
- No arguments.
-
- Move turtle to the origin - coordinates (0,0) and set its
- heading to its start-orientation (which depends on mode).
-
- Example (for a Turtle instance named turtle):
- >>> turtle.home()
- '''
- self.goto(0, 0)
- self.setheading(0)
-
-
- def setx(self, x):
- """Set the turtle's first coordinate to x
-
- Argument:
- x -- a number (integer or float)
-
- Set the turtle's first coordinate to x, leave second coordinate
- unchanged.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.position()
- (0.00, 240.00)
- >>> turtle.setx(10)
- >>> turtle.position()
- (10.00, 240.00)
- """
- self._goto(Vec2D(x, self._position[1]))
-
-
- def sety(self, y):
- """Set the turtle's second coordinate to y
-
- Argument:
- y -- a number (integer or float)
-
- Set the turtle's first coordinate to x, second coordinate remains
- unchanged.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.position()
- (0.00, 40.00)
- >>> turtle.sety(-10)
- >>> turtle.position()
- (0.00, -10.00)
- """
- self._goto(Vec2D(self._position[0], y))
-
-
- def distance(self, x, y = None):
- '''Return the distance from the turtle to (x,y) in turtle step units.
-
- Arguments:
- x -- a number or a pair/vector of numbers or a turtle instance
- y -- a number None None
-
- call: distance(x, y) # two coordinates
- --or: distance((x, y)) # a pair (tuple) of coordinates
- --or: distance(vec) # e.g. as returned by pos()
- --or: distance(mypen) # where mypen is another turtle
-
- Example (for a Turtle instance named turtle):
- >>> turtle.pos()
- (0.00, 0.00)
- >>> turtle.distance(30,40)
- 50.0
- >>> pen = Turtle()
- >>> pen.forward(77)
- >>> turtle.distance(pen)
- 77.0
- '''
- if y is not None:
- pos = Vec2D(x, y)
-
- if isinstance(x, Vec2D):
- pos = x
- elif isinstance(x, tuple):
- pos = Vec2D(*x)
- elif isinstance(x, TNavigator):
- pos = x._position
-
- return abs(pos - self._position)
-
-
- def towards(self, x, y = None):
- '''Return the angle of the line from the turtle\'s position to (x, y).
-
- Arguments:
- x -- a number or a pair/vector of numbers or a turtle instance
- y -- a number None None
-
- call: distance(x, y) # two coordinates
- --or: distance((x, y)) # a pair (tuple) of coordinates
- --or: distance(vec) # e.g. as returned by pos()
- --or: distance(mypen) # where mypen is another turtle
-
- Return the angle, between the line from turtle-position to position
- specified by x, y and the turtle\'s start orientation. (Depends on
- modes - "standard" or "logo")
-
- Example (for a Turtle instance named turtle):
- >>> turtle.pos()
- (10.00, 10.00)
- >>> turtle.towards(0,0)
- 225.0
- '''
- if y is not None:
- pos = Vec2D(x, y)
-
- if isinstance(x, Vec2D):
- pos = x
- elif isinstance(x, tuple):
- pos = Vec2D(*x)
- elif isinstance(x, TNavigator):
- pos = x._position
-
- (x, y) = pos - self._position
- result = round(math.atan2(y, x) * 180 / math.pi, 10) % 360
- result /= self._degreesPerAU
- return (self._angleOffset + self._angleOrient * result) % self._fullcircle
-
-
- def heading(self):
- """ Return the turtle's current heading.
-
- No arguments.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.left(67)
- >>> turtle.heading()
- 67.0
- """
- (x, y) = self._orient
- result = round(math.atan2(y, x) * 180 / math.pi, 10) % 360
- result /= self._degreesPerAU
- return (self._angleOffset + self._angleOrient * result) % self._fullcircle
-
-
- def setheading(self, to_angle):
- '''Set the orientation of the turtle to to_angle.
-
- Aliases: setheading | seth
-
- Argument:
- to_angle -- a number (integer or float)
-
- Set the orientation of the turtle to to_angle.
- Here are some common directions in degrees:
-
- standard - mode: logo-mode:
- -------------------|--------------------
- 0 - east 0 - north
- 90 - north 90 - east
- 180 - west 180 - south
- 270 - south 270 - west
-
- Example (for a Turtle instance named turtle):
- >>> turtle.setheading(90)
- >>> turtle.heading()
- 90
- '''
- angle = (to_angle - self.heading()) * self._angleOrient
- full = self._fullcircle
- angle = (angle + full / 2) % full - full / 2
- self._rotate(angle)
-
-
- def circle(self, radius, extent = None, steps = None):
- ''' Draw a circle with given radius.
-
- Arguments:
- radius -- a number
- extent (optional) -- a number
- steps (optional) -- an integer
-
- Draw a circle with given radius. The center is radius units left
- of the turtle; extent - an angle - determines which part of the
- circle is drawn. If extent is not given, draw the entire circle.
- If extent is not a full circle, one endpoint of the arc is the
- current pen position. Draw the arc in counterclockwise direction
- if radius is positive, otherwise in clockwise direction. Finally
- the direction of the turtle is changed by the amount of extent.
-
- As the circle is approximated by an inscribed regular polygon,
- steps determines the number of steps to use. If not given,
- it will be calculated automatically. Maybe used to draw regular
- polygons.
-
- call: circle(radius) # full circle
- --or: circle(radius, extent) # arc
- --or: circle(radius, extent, steps)
- --or: circle(radius, steps=6) # 6-sided polygon
-
- Example (for a Turtle instance named turtle):
- >>> turtle.circle(50)
- >>> turtle.circle(120, 180) # semicircle
- '''
- if self.undobuffer:
- self.undobuffer.push([
- 'seq'])
- self.undobuffer.cumulate = True
-
- speed = self.speed()
- if extent is None:
- extent = self._fullcircle
-
- if steps is None:
- frac = abs(extent) / self._fullcircle
- steps = 1 + int(min(11 + abs(radius) / 6, 59) * frac)
-
- w = 1 * extent / steps
- w2 = 0.5 * w
- l = 2 * radius * math.sin((w2 * math.pi / 180) * self._degreesPerAU)
- if radius < 0:
- l = -l
- w = -w
- w2 = -w2
-
- tr = self.tracer()
- dl = self._delay()
- if speed == 0:
- self.tracer(0, 0)
- else:
- self.speed(0)
- self._rotate(w2)
- for i in range(steps):
- self.speed(speed)
- self._go(l)
- self.speed(0)
- self._rotate(w)
-
- self._rotate(-w2)
- if speed == 0:
- self.tracer(tr, dl)
-
- self.speed(speed)
- if self.undobuffer:
- self.undobuffer.cumulate = False
-
-
-
- def speed(self, s = 0):
- '''dummy method - to be overwritten by child class'''
- pass
-
-
- def tracer(self, a = None, b = None):
- '''dummy method - to be overwritten by child class'''
- pass
-
-
- def _delay(self, n = None):
- '''dummy method - to be overwritten by child class'''
- pass
-
- fd = forward
- bk = back
- backward = back
- rt = right
- lt = left
- position = pos
- setpos = goto
- setposition = goto
- seth = setheading
-
-
- class TPen(object):
- '''Drawing part of the RawTurtle.
- Implements drawing properties.
- '''
-
- def __init__(self, resizemode = _CFG['resizemode']):
- self._resizemode = resizemode
- self.undobuffer = None
- TPen._reset(self)
-
-
- def _reset(self, pencolor = _CFG['pencolor'], fillcolor = _CFG['fillcolor']):
- self._pensize = 1
- self._shown = True
- self._pencolor = pencolor
- self._fillcolor = fillcolor
- self._drawing = True
- self._speed = 3
- self._stretchfactor = (1, 1)
- self._tilt = 0
- self._outlinewidth = 1
-
-
- def resizemode(self, rmode = None):
- '''Set resizemode to one of the values: "auto", "user", "noresize".
-
- (Optional) Argument:
- rmode -- one of the strings "auto", "user", "noresize"
-
- Different resizemodes have the following effects:
- - "auto" adapts the appearance of the turtle
- corresponding to the value of pensize.
- - "user" adapts the appearance of the turtle according to the
- values of stretchfactor and outlinewidth (outline),
- which are set by shapesize()
- - "noresize" no adaption of the turtle\'s appearance takes place.
- If no argument is given, return current resizemode.
- resizemode("user") is called by a call of shapesize with arguments.
-
-
- Examples (for a Turtle instance named turtle):
- >>> turtle.resizemode("noresize")
- >>> turtle.resizemode()
- \'noresize\'
- '''
- if rmode is None:
- return self._resizemode
- rmode = rmode.lower()
- if rmode in ('auto', 'user', 'noresize'):
- self.pen(resizemode = rmode)
-
-
-
- def pensize(self, width = None):
- '''Set or return the line thickness.
-
- Aliases: pensize | width
-
- Argument:
- width -- positive number
-
- Set the line thickness to width or return it. If resizemode is set
- to "auto" and turtleshape is a polygon, that polygon is drawn with
- the same line thickness. If no argument is given, current pensize
- is returned.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.pensize()
- 1
- turtle.pensize(10) # from here on lines of width 10 are drawn
- '''
- if width is None:
- return self._pensize
- self.pen(pensize = width)
-
-
- def penup(self):
- '''Pull the pen up -- no drawing when moving.
-
- Aliases: penup | pu | up
-
- No argument
-
- Example (for a Turtle instance named turtle):
- >>> turtle.penup()
- '''
- if not self._drawing:
- return None
- self.pen(pendown = False)
-
-
- def pendown(self):
- '''Pull the pen down -- drawing when moving.
-
- Aliases: pendown | pd | down
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.pendown()
- '''
- if self._drawing:
- return None
- self.pen(pendown = True)
-
-
- def isdown(self):
- """Return True if pen is down, False if it's up.
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.penup()
- >>> turtle.isdown()
- False
- >>> turtle.pendown()
- >>> turtle.isdown()
- True
- """
- return self._drawing
-
-
- def speed(self, speed = None):
- """ Return or set the turtle's speed.
-
- Optional argument:
- speed -- an integer in the range 0..10 or a speedstring (see below)
-
- Set the turtle's speed to an integer value in the range 0 .. 10.
- If no argument is given: return current speed.
-
- If input is a number greater than 10 or smaller than 0.5,
- speed is set to 0.
- Speedstrings are mapped to speedvalues in the following way:
- 'fastest' : 0
- 'fast' : 10
- 'normal' : 6
- 'slow' : 3
- 'slowest' : 1
- speeds from 1 to 10 enforce increasingly faster animation of
- line drawing and turtle turning.
-
- Attention:
- speed = 0 : *no* animation takes place. forward/back makes turtle jump
- and likewise left/right make the turtle turn instantly.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.speed(3)
- """
- speeds = {
- 'fastest': 0,
- 'fast': 10,
- 'normal': 6,
- 'slow': 3,
- 'slowest': 1 }
- if speed is None:
- return self._speed
- if speed in speeds:
- speed = speeds[speed]
- elif speed < speed:
- pass
- elif speed < 10.5:
- speed = int(round(speed))
- else:
- speed = 0
- self.pen(speed = speed)
-
-
- def color(self, *args):
- """Return or set the pencolor and fillcolor.
-
- Arguments:
- Several input formats are allowed.
- They use 0, 1, 2, or 3 arguments as follows:
-
- color()
- Return the current pencolor and the current fillcolor
- as a pair of color specification strings as are returned
- by pencolor and fillcolor.
- color(colorstring), color((r,g,b)), color(r,g,b)
- inputs as in pencolor, set both, fillcolor and pencolor,
- to the given value.
- color(colorstring1, colorstring2),
- color((r1,g1,b1), (r2,g2,b2))
- equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
- and analogously, if the other input format is used.
-
- If turtleshape is a polygon, outline and interior of that polygon
- is drawn with the newly set colors.
- For mor info see: pencolor, fillcolor
-
- Example (for a Turtle instance named turtle):
- >>> turtle.color('red', 'green')
- >>> turtle.color()
- ('red', 'green')
- >>> colormode(255)
- >>> color((40, 80, 120), (160, 200, 240))
- >>> color()
- ('#285078', '#a0c8f0')
- """
- if args:
- l = len(args)
- if l == 1:
- pcolor = fcolor = args[0]
- elif l == 2:
- (pcolor, fcolor) = args
- elif l == 3:
- pcolor = fcolor = args
-
- pcolor = self._colorstr(pcolor)
- fcolor = self._colorstr(fcolor)
- self.pen(pencolor = pcolor, fillcolor = fcolor)
- else:
- return (self._color(self._pencolor), self._color(self._fillcolor))
- return args
-
-
- def pencolor(self, *args):
- ''' Return or set the pencolor.
-
- Arguments:
- Four input formats are allowed:
- - pencolor()
- Return the current pencolor as color specification string,
- possibly in hex-number format (see example).
- May be used as input to another color/pencolor/fillcolor call.
- - pencolor(colorstring)
- s is a Tk color specification string, such as "red" or "yellow"
- - pencolor((r, g, b))
- *a tuple* of r, g, and b, which represent, an RGB color,
- and each of r, g, and b are in the range 0..colormode,
- where colormode is either 1.0 or 255
- - pencolor(r, g, b)
- r, g, and b represent an RGB color, and each of r, g, and b
- are in the range 0..colormode
-
- If turtleshape is a polygon, the outline of that polygon is drawn
- with the newly set pencolor.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.pencolor(\'brown\')
- >>> tup = (0.2, 0.8, 0.55)
- >>> turtle.pencolor(tup)
- >>> turtle.pencolor()
- \'#33cc8c\'
- '''
- if args:
- color = self._colorstr(args)
- if color == self._pencolor:
- return None
- self.pen(pencolor = color)
- else:
- return self._color(self._pencolor)
- return color == self._pencolor
-
-
- def fillcolor(self, *args):
- ''' Return or set the fillcolor.
-
- Arguments:
- Four input formats are allowed:
- - fillcolor()
- Return the current fillcolor as color specification string,
- possibly in hex-number format (see example).
- May be used as input to another color/pencolor/fillcolor call.
- - fillcolor(colorstring)
- s is a Tk color specification string, such as "red" or "yellow"
- - fillcolor((r, g, b))
- *a tuple* of r, g, and b, which represent, an RGB color,
- and each of r, g, and b are in the range 0..colormode,
- where colormode is either 1.0 or 255
- - fillcolor(r, g, b)
- r, g, and b represent an RGB color, and each of r, g, and b
- are in the range 0..colormode
-
- If turtleshape is a polygon, the interior of that polygon is drawn
- with the newly set fillcolor.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.fillcolor(\'violet\')
- >>> col = turtle.pencolor()
- >>> turtle.fillcolor(col)
- >>> turtle.fillcolor(0, .5, 0)
- '''
- if args:
- color = self._colorstr(args)
- if color == self._fillcolor:
- return None
- self.pen(fillcolor = color)
- else:
- return self._color(self._fillcolor)
- return color == self._fillcolor
-
-
- def showturtle(self):
- '''Makes the turtle visible.
-
- Aliases: showturtle | st
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.hideturtle()
- >>> turtle.showturtle()
- '''
- self.pen(shown = True)
-
-
- def hideturtle(self):
- """Makes the turtle invisible.
-
- Aliases: hideturtle | ht
-
- No argument.
-
- It's a good idea to do this while you're in the
- middle of a complicated drawing, because hiding
- the turtle speeds up the drawing observably.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.hideturtle()
- """
- self.pen(shown = False)
-
-
- def isvisible(self):
- """Return True if the Turtle is shown, False if it's hidden.
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.hideturtle()
- >>> print turtle.isvisible():
- False
- """
- return self._shown
-
-
- def pen(self, pen = None, **pendict):
- '''Return or set the pen\'s attributes.
-
- Arguments:
- pen -- a dictionary with some or all of the below listed keys.
- **pendict -- one or more keyword-arguments with the below
- listed keys as keywords.
-
- Return or set the pen\'s attributes in a \'pen-dictionary\'
- with the following key/value pairs:
- "shown" : True/False
- "pendown" : True/False
- "pencolor" : color-string or color-tuple
- "fillcolor" : color-string or color-tuple
- "pensize" : positive number
- "speed" : number in range 0..10
- "resizemode" : "auto" or "user" or "noresize"
- "stretchfactor": (positive number, positive number)
- "outline" : positive number
- "tilt" : number
-
- This dictionary can be used as argument for a subsequent
- pen()-call to restore the former pen-state. Moreover one
- or more of these attributes can be provided as keyword-arguments.
- This can be used to set several pen attributes in one statement.
-
-
- Examples (for a Turtle instance named turtle):
- >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
- >>> turtle.pen()
- {\'pensize\': 10, \'shown\': True, \'resizemode\': \'auto\', \'outline\': 1,
- \'pencolor\': \'red\', \'pendown\': True, \'fillcolor\': \'black\',
- \'stretchfactor\': (1,1), \'speed\': 3}
- >>> penstate=turtle.pen()
- >>> turtle.color("yellow","")
- >>> turtle.penup()
- >>> turtle.pen()
- {\'pensize\': 10, \'shown\': True, \'resizemode\': \'auto\', \'outline\': 1,
- \'pencolor\': \'yellow\', \'pendown\': False, \'fillcolor\': \'\',
- \'stretchfactor\': (1,1), \'speed\': 3}
- >>> p.pen(penstate, fillcolor="green")
- >>> p.pen()
- {\'pensize\': 10, \'shown\': True, \'resizemode\': \'auto\', \'outline\': 1,
- \'pencolor\': \'red\', \'pendown\': True, \'fillcolor\': \'green\',
- \'stretchfactor\': (1,1), \'speed\': 3}
- '''
- _pd = {
- 'shown': self._shown,
- 'pendown': self._drawing,
- 'pencolor': self._pencolor,
- 'fillcolor': self._fillcolor,
- 'pensize': self._pensize,
- 'speed': self._speed,
- 'resizemode': self._resizemode,
- 'stretchfactor': self._stretchfactor,
- 'outline': self._outlinewidth,
- 'tilt': self._tilt }
- if not pen or pendict:
- return _pd
- if isinstance(pen, dict):
- p = pen
- else:
- p = { }
- p.update(pendict)
- _p_buf = { }
- for key in p:
- _p_buf[key] = _pd[key]
-
- if self.undobuffer:
- self.undobuffer.push(('pen', _p_buf))
-
- newLine = False
- if 'pendown' in p:
- if self._drawing != p['pendown']:
- newLine = True
-
-
- if 'pencolor' in p:
- if isinstance(p['pencolor'], tuple):
- p['pencolor'] = self._colorstr((p['pencolor'],))
-
- if self._pencolor != p['pencolor']:
- newLine = True
-
-
- if 'pensize' in p:
- if self._pensize != p['pensize']:
- newLine = True
-
-
- if newLine:
- self._newLine()
-
- if 'pendown' in p:
- self._drawing = p['pendown']
-
- if 'pencolor' in p:
- self._pencolor = p['pencolor']
-
- if 'pensize' in p:
- self._pensize = p['pensize']
-
- if 'fillcolor' in p:
- if isinstance(p['fillcolor'], tuple):
- p['fillcolor'] = self._colorstr((p['fillcolor'],))
-
- self._fillcolor = p['fillcolor']
-
- if 'speed' in p:
- self._speed = p['speed']
-
- if 'resizemode' in p:
- self._resizemode = p['resizemode']
-
- if 'stretchfactor' in p:
- sf = p['stretchfactor']
- if isinstance(sf, (int, float)):
- sf = (sf, sf)
-
- self._stretchfactor = sf
-
- if 'outline' in p:
- self._outlinewidth = p['outline']
-
- if 'shown' in p:
- self._shown = p['shown']
-
- if 'tilt' in p:
- self._tilt = p['tilt']
-
- self._update()
-
-
- def _newLine(self, usePos = True):
- '''dummy method - to be overwritten by child class'''
- pass
-
-
- def _update(self, count = True, forced = False):
- '''dummy method - to be overwritten by child class'''
- pass
-
-
- def _color(self, args):
- '''dummy method - to be overwritten by child class'''
- pass
-
-
- def _colorstr(self, args):
- '''dummy method - to be overwritten by child class'''
- pass
-
- width = pensize
- up = penup
- pu = penup
- pd = pendown
- down = pendown
- st = showturtle
- ht = hideturtle
-
-
- class _TurtleImage(object):
- '''Helper class: Datatype to store Turtle attributes
- '''
-
- def __init__(self, screen, shapeIndex):
- self.screen = screen
- self._type = None
- self._setshape(shapeIndex)
-
-
- def _setshape(self, shapeIndex):
- screen = self.screen
- self.shapeIndex = shapeIndex
- if 'polygon' == 'polygon':
- pass
- elif 'polygon' == screen._shapes[shapeIndex]._type:
- return None
- if 'image' == 'image':
- pass
- elif 'image' == screen._shapes[shapeIndex]._type:
- return None
- if self._type in ('image', 'polygon'):
- screen._delete(self._item)
- elif self._type == 'compound':
- for item in self._item:
- screen._delete(item)
-
-
- self._type = screen._shapes[shapeIndex]._type
- if self._type == 'polygon':
- self._item = screen._createpoly()
- elif self._type == 'image':
- self._item = screen._createimage(screen._shapes['blank']._data)
- elif self._type == 'compound':
- self._item = [ screen._createpoly() for item in screen._shapes[shapeIndex]._data ]
-
-
-
-
- class RawTurtle(TPen, TNavigator):
- '''Animation part of the RawTurtle.
- Puts RawTurtle upon a TurtleScreen and provides tools for
- its animation.
- '''
- screens = []
-
- def __init__(self, canvas = None, shape = _CFG['shape'], undobuffersize = _CFG['undobuffersize'], visible = _CFG['visible']):
- if isinstance(canvas, _Screen):
- self.screen = canvas
- elif isinstance(canvas, TurtleScreen):
- if canvas not in RawTurtle.screens:
- RawTurtle.screens.append(canvas)
-
- self.screen = canvas
- elif isinstance(canvas, (ScrolledCanvas, Canvas)):
- for screen in RawTurtle.screens:
- if screen.cv == canvas:
- self.screen = screen
- break
- continue
- else:
- self.screen = TurtleScreen(canvas)
- else:
- raise TurtleGraphicsError('bad cavas argument %s' % canvas)
- screen = isinstance(canvas, _Screen).screen
- TNavigator.__init__(self, screen.mode())
- TPen.__init__(self)
- screen._turtles.append(self)
- self.drawingLineItem = screen._createline()
- self.turtle = _TurtleImage(screen, shape)
- self._poly = None
- self._creatingPoly = False
- self._fillitem = None
- self._fillpath = None
- self._shown = visible
- self._hidden_from_screen = False
- self.currentLineItem = screen._createline()
- self.currentLine = [
- self._position]
- self.items = [
- self.currentLineItem]
- self.stampItems = []
- self._undobuffersize = undobuffersize
- self.undobuffer = Tbuffer(undobuffersize)
- self._update()
-
-
- def reset(self):
- """Delete the turtle's drawings and restore its default values.
-
- No argument.
- ,
- Delete the turtle's drawings from the screen, re-center the turtle
- and set variables to the default values.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.position()
- (0.00,-22.00)
- >>> turtle.heading()
- 100.0
- >>> turtle.reset()
- >>> turtle.position()
- (0.00,0.00)
- >>> turtle.heading()
- 0.0
- """
- TNavigator.reset(self)
- TPen._reset(self)
- self._clear()
- self._drawturtle()
- self._update()
-
-
- def setundobuffer(self, size):
- '''Set or disable undobuffer.
-
- Argument:
- size -- an integer or None
-
- If size is an integer an empty undobuffer of given size is installed.
- Size gives the maximum number of turtle-actions that can be undone
- by the undo() function.
- If size is None, no undobuffer is present.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.setundobuffer(42)
- '''
- if size is None:
- self.undobuffer = None
- else:
- self.undobuffer = Tbuffer(size)
-
-
- def undobufferentries(self):
- '''Return count of entries in the undobuffer.
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> while undobufferentries():
- undo()
- '''
- if self.undobuffer is None:
- return 0
- return self.undobuffer.nr_of_items()
-
-
- def _clear(self):
- """Delete all of pen's drawings"""
- self._fillitem = None
- self._fillpath = None
- for item in self.items:
- self.screen._delete(item)
-
- self.currentLineItem = self.screen._createline()
- self.currentLine = []
- if self._drawing:
- self.currentLine.append(self._position)
-
- self.items = [
- self.currentLineItem]
- self.clearstamps()
- self.setundobuffer(self._undobuffersize)
-
-
- def clear(self):
- """Delete the turtle's drawings from the screen. Do not move turtle.
-
- No arguments.
-
- Delete the turtle's drawings from the screen. Do not move turtle.
- State and position of the turtle as well as drawings of other
- turtles are not affected.
-
- Examples (for a Turtle instance named turtle):
- >>> turtle.clear()
- """
- self._clear()
- self._update()
-
-
- def _update_data(self):
- self.screen._incrementudc()
- if self.screen._updatecounter != 0:
- return None
- if len(self.currentLine) > 1:
- self.screen._drawline(self.currentLineItem, self.currentLine, self._pencolor, self._pensize)
-
-
-
- def _update(self):
- '''Perform a Turtle-data update.
- '''
- screen = self.screen
- if screen._tracing == 0:
- return None
- if screen._tracing == 1:
- self._update_data()
- self._drawturtle()
- screen._update()
- screen._delay(screen._delayvalue)
- else:
- self._update_data()
- if screen._updatecounter == 0:
- for t in screen.turtles():
- t._drawturtle()
-
- screen._update()
-
-
-
- def tracer(self, flag = None, delay = None):
- '''Turns turtle animation on/off and set delay for update drawings.
-
- Optional arguments:
- n -- nonnegative integer
- delay -- nonnegative integer
-
- If n is given, only each n-th regular screen update is really performed.
- (Can be used to accelerate the drawing of complex graphics.)
- Second arguments sets delay value (see RawTurtle.delay())
-
- Example (for a Turtle instance named turtle):
- >>> turtle.tracer(8, 25)
- >>> dist = 2
- >>> for i in range(200):
- turtle.fd(dist)
- turtle.rt(90)
- dist += 2
- '''
- return self.screen.tracer(flag, delay)
-
-
- def _color(self, args):
- return self.screen._color(args)
-
-
- def _colorstr(self, args):
- return self.screen._colorstr(args)
-
-
- def _cc(self, args):
- '''Convert colortriples to hexstrings.
- '''
- if isinstance(args, str):
- return args
-
- try:
- (r, g, b) = args
- except:
- isinstance(args, str)
- raise TurtleGraphicsError('bad color arguments: %s' % str(args))
-
- if r <= r:
- pass
- elif r <= 255:
- if g <= g:
- pass
- elif g <= 255:
- if b <= b:
- pass
- elif not b <= 255:
- raise TurtleGraphicsError('bad color sequence: %s' % str(args))
-
- return '#%02x%02x%02x' % (r, g, b)
-
-
- def clone(self):
- '''Create and return a clone of the turtle.
-
- No argument.
-
- Create and return a clone of the turtle with same position, heading
- and turtle properties.
-
- Example (for a Turtle instance named mick):
- mick = Turtle()
- joe = mick.clone()
- '''
- screen = self.screen
- self._newLine(self._drawing)
- turtle = self.turtle
- self.screen = None
- self.turtle = None
- q = deepcopy(self)
- self.screen = screen
- self.turtle = turtle
- q.screen = screen
- q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
- screen._turtles.append(q)
- ttype = screen._shapes[self.turtle.shapeIndex]._type
- if ttype == 'polygon':
- q.turtle._item = screen._createpoly()
- elif ttype == 'image':
- q.turtle._item = screen._createimage(screen._shapes['blank']._data)
- elif ttype == 'compound':
- q.turtle._item = [ screen._createpoly() for item in screen._shapes[self.turtle.shapeIndex]._data ]
-
- q.currentLineItem = screen._createline()
- q._update()
- return q
-
-
- def shape(self, name = None):
- '''Set turtle shape to shape with given name / return current shapename.
-
- Optional argument:
- name -- a string, which is a valid shapename
-
- Set turtle shape to shape with given name or, if name is not given,
- return name of current shape.
- Shape with name must exist in the TurtleScreen\'s shape dictionary.
- Initially there are the following polygon shapes:
- \'arrow\', \'turtle\', \'circle\', \'square\', \'triangle\', \'classic\'.
- To learn about how to deal with shapes see Screen-method register_shape.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.shape()
- \'arrow\'
- >>> turtle.shape("turtle")
- >>> turtle.shape()
- \'turtle\'
- '''
- if name is None:
- return self.turtle.shapeIndex
- if name not in self.screen.getshapes():
- raise TurtleGraphicsError('There is no shape named %s' % name)
- name not in self.screen.getshapes()
- self.turtle._setshape(name)
- self._update()
-
-
- def shapesize(self, stretch_wid = None, stretch_len = None, outline = None):
- '''Set/return turtle\'s stretchfactors/outline. Set resizemode to "user".
-
- Optinonal arguments:
- stretch_wid : positive number
- stretch_len : positive number
- outline : positive number
-
- Return or set the pen\'s attributes x/y-stretchfactors and/or outline.
- Set resizemode to "user".
- If and only if resizemode is set to "user", the turtle will be displayed
- stretched according to its stretchfactors:
- stretch_wid is stretchfactor perpendicular to orientation
- stretch_len is stretchfactor in direction of turtles orientation.
- outline determines the width of the shapes\'s outline.
-
- Examples (for a Turtle instance named turtle):
- >>> turtle.resizemode("user")
- >>> turtle.shapesize(5, 5, 12)
- >>> turtle.shapesize(outline=8)
- '''
- if stretch_wid is None and stretch_len is None and outline == None:
- (stretch_wid, stretch_len) = self._stretchfactor
- return (stretch_wid, stretch_len, self._outlinewidth)
- if stretch_wid is not None:
- if stretch_len is None:
- stretchfactor = (stretch_wid, stretch_wid)
- else:
- stretchfactor = (stretch_wid, stretch_len)
- elif stretch_len is not None:
- stretchfactor = (self._stretchfactor[0], stretch_len)
- else:
- stretchfactor = self._stretchfactor
- if outline is None:
- outline = self._outlinewidth
-
- self.pen(resizemode = 'user', stretchfactor = stretchfactor, outline = outline)
-
-
- def settiltangle(self, angle):
- '''Rotate the turtleshape to point in the specified direction
-
- Optional argument:
- angle -- number
-
- Rotate the turtleshape to point in the direction specified by angle,
- regardless of its current tilt-angle. DO NOT change the turtle\'s
- heading (direction of movement).
-
-
- Examples (for a Turtle instance named turtle):
- >>> turtle.shape("circle")
- >>> turtle.shapesize(5,2)
- >>> turtle.settiltangle(45)
- >>> stamp()
- >>> turtle.fd(50)
- >>> turtle.settiltangle(-45)
- >>> stamp()
- >>> turtle.fd(50)
- '''
- tilt = -angle * self._degreesPerAU * self._angleOrient
- tilt = tilt * math.pi / 180 % 2 * math.pi
- self.pen(resizemode = 'user', tilt = tilt)
-
-
- def tiltangle(self):
- '''Return the current tilt-angle.
-
- No argument.
-
- Return the current tilt-angle, i. e. the angle between the
- orientation of the turtleshape and the heading of the turtle
- (its direction of movement).
-
- Examples (for a Turtle instance named turtle):
- >>> turtle.shape("circle")
- >>> turtle.shapesize(5,2)
- >>> turtle.tilt(45)
- >>> turtle.tiltangle()
- >>>
- '''
- tilt = -(self._tilt) * (180 / math.pi) * self._angleOrient
- return tilt / self._degreesPerAU % self._fullcircle
-
-
- def tilt(self, angle):
- '''Rotate the turtleshape by angle.
-
- Argument:
- angle - a number
-
- Rotate the turtleshape by angle from its current tilt-angle,
- but do NOT change the turtle\'s heading (direction of movement).
-
- Examples (for a Turtle instance named turtle):
- >>> turtle.shape("circle")
- >>> turtle.shapesize(5,2)
- >>> turtle.tilt(30)
- >>> turtle.fd(50)
- >>> turtle.tilt(30)
- >>> turtle.fd(50)
- '''
- self.settiltangle(angle + self.tiltangle())
-
-
- def _polytrafo(self, poly):
- '''Computes transformed polygon shapes from a shape
- according to current position and heading.
- '''
- screen = self.screen
- (p0, p1) = self._position
- (e0, e1) = self._orient
- e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
- (e0, e1) = (1 / abs(e)) * e
- return [ (p0 + (e1 * x + e0 * y) / screen.xscale, p1 + (-e0 * x + e1 * y) / screen.yscale) for x, y in poly ]
-
-
- def _drawturtle(self):
- '''Manages the correct rendering of the turtle with respect to
- its shape, resizemode, stretch and tilt etc.'''
- screen = self.screen
- shape = screen._shapes[self.turtle.shapeIndex]
- ttype = shape._type
- titem = self.turtle._item
- if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
- self._hidden_from_screen = False
- tshape = shape._data
- if ttype == 'polygon':
- if self._resizemode == 'noresize':
- w = 1
- shape = tshape
- elif self._resizemode == 'auto':
- lx = ly = max(1, self._pensize / 5)
- w = self._pensize
- tiltangle = 0
- elif self._resizemode == 'user':
- (lx, ly) = self._stretchfactor
- w = self._outlinewidth
- tiltangle = self._tilt
-
- shape = [ (lx * x, ly * y) for x, y in tshape ]
- t0 = math.sin(tiltangle)
- t1 = math.cos(tiltangle)
- shape = [ (t1 * x + t0 * y, -t0 * x + t1 * y) for x, y in shape ]
- shape = self._polytrafo(shape)
- fc = self._fillcolor
- oc = self._pencolor
- screen._drawpoly(titem, shape, fill = fc, outline = oc, width = w, top = True)
- elif ttype == 'image':
- screen._drawimage(titem, self._position, tshape)
- elif ttype == 'compound':
- (lx, ly) = self._stretchfactor
- w = self._outlinewidth
- for poly, fc, oc in zip(titem, tshape):
- poly = [ (lx * x, ly * y) for x, y in poly ]
- poly = self._polytrafo(poly)
- screen._drawpoly(item, poly, fill = self._cc(fc), outline = self._cc(oc), width = w, top = True)
-
-
- elif self._hidden_from_screen:
- return None
- if ttype == 'polygon':
- screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), '', '')
- elif ttype == 'image':
- screen._drawimage(titem, self._position, screen._shapes['blank']._data)
- elif ttype == 'compound':
- for item in titem:
- screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), '', '')
-
-
- self._hidden_from_screen = True
-
-
- def stamp(self):
- '''Stamp a copy of the turtleshape onto the canvas and return its id.
-
- No argument.
-
- Stamp a copy of the turtle shape onto the canvas at the current
- turtle position. Return a stamp_id for that stamp, which can be
- used to delete it by calling clearstamp(stamp_id).
-
- Example (for a Turtle instance named turtle):
- >>> turtle.color("blue")
- >>> turtle.stamp()
- 13
- >>> turtle.fd(50)
- '''
- screen = self.screen
- shape = screen._shapes[self.turtle.shapeIndex]
- ttype = shape._type
- tshape = shape._data
- if ttype == 'polygon':
- stitem = screen._createpoly()
- if self._resizemode == 'noresize':
- w = 1
- shape = tshape
- elif self._resizemode == 'auto':
- lx = ly = max(1, self._pensize / 5)
- w = self._pensize
- tiltangle = 0
- elif self._resizemode == 'user':
- (lx, ly) = self._stretchfactor
- w = self._outlinewidth
- tiltangle = self._tilt
-
- shape = [ (lx * x, ly * y) for x, y in tshape ]
- t0 = math.sin(tiltangle)
- t1 = math.cos(tiltangle)
- shape = [ (t1 * x + t0 * y, -t0 * x + t1 * y) for x, y in shape ]
- shape = self._polytrafo(shape)
- fc = self._fillcolor
- oc = self._pencolor
- screen._drawpoly(stitem, shape, fill = fc, outline = oc, width = w, top = True)
- elif ttype == 'image':
- stitem = screen._createimage('')
- screen._drawimage(stitem, self._position, tshape)
- elif ttype == 'compound':
- stitem = []
- for element in tshape:
- item = screen._createpoly()
- stitem.append(item)
-
- stitem = tuple(stitem)
- (lx, ly) = self._stretchfactor
- w = self._outlinewidth
- for poly, fc, oc in zip(stitem, tshape):
- poly = [ (lx * x, ly * y) for x, y in poly ]
- poly = self._polytrafo(poly)
- screen._drawpoly(item, poly, fill = self._cc(fc), outline = self._cc(oc), width = w, top = True)
-
-
- self.stampItems.append(stitem)
- self.undobuffer.push(('stamp', stitem))
- return stitem
-
-
- def _clearstamp(self, stampid):
- '''does the work for clearstamp() and clearstamps()
- '''
- if stampid in self.stampItems:
- if isinstance(stampid, tuple):
- for subitem in stampid:
- self.screen._delete(subitem)
-
- else:
- self.screen._delete(stampid)
- self.stampItems.remove(stampid)
-
- item = ('stamp', stampid)
- buf = self.undobuffer
- if item not in buf.buffer:
- return None
- index = buf.buffer.index(item)
- buf.buffer.remove(item)
- if index <= buf.ptr:
- buf.ptr = (buf.ptr - 1) % buf.bufsize
-
- buf.buffer.insert((buf.ptr + 1) % buf.bufsize, [
- None])
-
-
- def clearstamp(self, stampid):
- '''Delete stamp with given stampid
-
- Argument:
- stampid - an integer, must be return value of previous stamp() call.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.color("blue")
- >>> astamp = turtle.stamp()
- >>> turtle.fd(50)
- >>> turtle.clearstamp(astamp)
- '''
- self._clearstamp(stampid)
- self._update()
-
-
- def clearstamps(self, n = None):
- """Delete all or first/last n of turtle's stamps.
-
- Optional argument:
- n -- an integer
-
- If n is None, delete all of pen's stamps,
- else if n > 0 delete first n stamps
- else if n < 0 delete last n stamps.
-
- Example (for a Turtle instance named turtle):
- >>> for i in range(8):
- turtle.stamp(); turtle.fd(30)
- ...
- >>> turtle.clearstamps(2)
- >>> turtle.clearstamps(-2)
- >>> turtle.clearstamps()
- """
- if n is None:
- toDelete = self.stampItems[:]
- elif n >= 0:
- toDelete = self.stampItems[:n]
- else:
- toDelete = self.stampItems[n:]
- for item in toDelete:
- self._clearstamp(item)
-
- self._update()
-
-
- def _goto(self, end):
- '''Move the pen to the point end, thereby drawing a line
- if pen is down. All other methodes for turtle movement depend
- on this one.
- '''
- go_modes = (self._drawing, self._pencolor, self._pensize, isinstance(self._fillpath, list))
- screen = self.screen
- undo_entry = ('go', self._position, end, go_modes, (self.currentLineItem, self.currentLine[:], screen._pointlist(self.currentLineItem), self.items[:]))
- if self.undobuffer:
- self.undobuffer.push(undo_entry)
-
- start = self._position
- if self._speed and screen._tracing == 1:
- diff = end - start
- diffsq = (diff[0] * screen.xscale) ** 2 + (diff[1] * screen.yscale) ** 2
- nhops = 1 + int(diffsq ** 0.5 / (3 * 1.1 ** self._speed * self._speed))
- delta = diff * (1 / nhops)
- for n in range(1, nhops):
- if n == 1:
- top = True
- else:
- top = False
- self._position = start + delta * n
- if self._drawing:
- screen._drawline(self.drawingLineItem, (start, self._position), self._pencolor, self._pensize, top)
-
- self._update()
-
- if self._drawing:
- screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)), fill = '', width = self._pensize)
-
-
- if self._drawing:
- self.currentLine.append(end)
-
- if isinstance(self._fillpath, list):
- self._fillpath.append(end)
-
- self._position = end
- if self._creatingPoly:
- self._poly.append(end)
-
- if len(self.currentLine) > 42:
- self._newLine()
-
- self._update()
-
-
- def _undogoto(self, entry):
- '''Reverse a _goto. Used for undo()
- '''
- (old, new, go_modes, coodata) = entry
- (drawing, pc, ps, filling) = go_modes
- (cLI, cL, pl, items) = coodata
- screen = self.screen
- if abs(self._position - new) > 0.5:
- print 'undogoto: HALLO-DA-STIMMT-WAS-NICHT!'
-
- self.currentLineItem = cLI
- self.currentLine = cL
- if pl == [
- (0, 0),
- (0, 0)]:
- usepc = ''
- else:
- usepc = pc
- screen._drawline(cLI, pl, fill = usepc, width = ps)
- todelete = _[1]
- for i in todelete:
- screen._delete(i)
- self.items.remove(i)
-
- start = old
- if self._speed and screen._tracing == 1:
- diff = old - new
- diffsq = (diff[0] * screen.xscale) ** 2 + (diff[1] * screen.yscale) ** 2
- nhops = 1 + int(diffsq ** 0.5 / (3 * 1.1 ** self._speed * self._speed))
- delta = diff * (1 / nhops)
- for n in range(1, nhops):
- self._position = new + delta * n
- if drawing:
- screen._drawline(self.drawingLineItem, (start, self._position), pc, ps, top)
-
- self._update()
-
- if drawing:
- screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)), fill = '', width = ps)
-
-
- self._position = old
- if self._creatingPoly:
- if len(self._poly) > 0:
- self._poly.pop()
-
- if self._poly == []:
- self._creatingPoly = False
- self._poly = None
-
-
- if filling:
- if self._fillpath == []:
- self._fillpath = None
- print 'Unwahrscheinlich in _undogoto!'
- elif self._fillpath is not None:
- self._fillpath.pop()
-
-
- self._update()
-
-
- def _rotate(self, angle):
- '''Turns pen clockwise by angle.
- '''
- if self.undobuffer:
- self.undobuffer.push(('rot', angle, self._degreesPerAU))
-
- angle *= self._degreesPerAU
- neworient = self._orient.rotate(angle)
- tracing = self.screen._tracing
- if tracing == 1 and self._speed > 0:
- anglevel = 3 * self._speed
- steps = 1 + int(abs(angle) / anglevel)
- delta = 1 * angle / steps
- for _ in range(steps):
- self._orient = self._orient.rotate(delta)
- self._update()
-
-
- self._orient = neworient
- self._update()
-
-
- def _newLine(self, usePos = True):
- '''Closes current line item and starts a new one.
- Remark: if current line became too long, animation
- performance (via _drawline) slowed down considerably.
- '''
- if len(self.currentLine) > 1:
- self.screen._drawline(self.currentLineItem, self.currentLine, self._pencolor, self._pensize)
- self.currentLineItem = self.screen._createline()
- self.items.append(self.currentLineItem)
- else:
- self.screen._drawline(self.currentLineItem, top = True)
- self.currentLine = []
- if usePos:
- self.currentLine = [
- self._position]
-
-
-
- def fill(self, flag = None):
- '''Call fill(True) before drawing a shape to fill, fill(False) when done.
-
- Optional argument:
- flag -- True/False (or 1/0 respectively)
-
- Call fill(True) before drawing the shape you want to fill,
- and fill(False) when done.
- When used without argument: return fillstate (True if filling,
- False else)
-
- Example (for a Turtle instance named turtle):
- >>> turtle.fill(True)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.fill(False)
- '''
- filling = isinstance(self._fillpath, list)
- if flag is None:
- return filling
- screen = self.screen
- if flag:
- self._fillitem = self.screen._createpoly()
- self.items.append(self._fillitem)
- self._fillpath = [
- self._position]
- entry2 = ('beginfill', self._fillitem)
- self._newLine()
- else:
- self._fillitem = None
- self._fillpath = None
- if self.undobuffer:
- if entry1 == ():
- if entry2 != ():
- self.undobuffer.push(entry2)
-
- elif entry2 == ():
- self.undobuffer.push(entry1)
- else:
- self.undobuffer.push([
- 'seq',
- entry1,
- entry2])
-
- self._update()
-
-
- def begin_fill(self):
- '''Called just before drawing a shape to be filled.
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.begin_fill()
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.end_fill()
- '''
- self.fill(True)
-
-
- def end_fill(self):
- '''Fill the shape drawn after the call begin_fill().
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.begin_fill()
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.left(90)
- >>> turtle.forward(100)
- >>> turtle.end_fill()
- '''
- self.fill(False)
-
-
- def dot(self, size = None, *color):
- '''Draw a dot with diameter size, using color.
-
- Optional argumentS:
- size -- an integer >= 1 (if given)
- color -- a colorstring or a numeric color tuple
-
- Draw a circular dot with diameter size, using color.
- If size is not given, the maximum of pensize+4 and 2*pensize is used.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.dot()
- >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
- '''
- if not color:
- if isinstance(size, (str, tuple)):
- color = self._colorstr(size)
- size = self._pensize + max(self._pensize, 4)
- else:
- color = self._pencolor
- if not size:
- size = self._pensize + max(self._pensize, 4)
-
- elif size is None:
- size = self._pensize + max(self._pensize, 4)
-
- color = self._colorstr(color)
- if hasattr(self.screen, '_dot'):
- item = self.screen._dot(self._position, size, color)
- self.items.append(item)
- if self.undobuffer:
- self.undobuffer.push(('dot', item))
-
- else:
- pen = self.pen()
- if self.undobuffer:
- self.undobuffer.push([
- 'seq'])
- self.undobuffer.cumulate = True
-
-
- try:
- if self.resizemode() == 'auto':
- self.ht()
-
- self.pendown()
- self.pensize(size)
- self.pencolor(color)
- self.forward(0)
- finally:
- self.pen(pen)
-
- if self.undobuffer:
- self.undobuffer.cumulate = False
-
-
-
- def _write(self, txt, align, font):
- '''Performs the writing for write()
- '''
- (item, end) = self.screen._write(self._position, txt, align, font, self._pencolor)
- self.items.append(item)
- if self.undobuffer:
- self.undobuffer.push(('wri', item))
-
- return end
-
-
- def write(self, arg, move = False, align = 'left', font = ('Arial', 8, 'normal')):
- '''Write text at the current turtle position.
-
- Arguments:
- arg -- info, which is to be written to the TurtleScreen
- move (optional) -- True/False
- align (optional) -- one of the strings "left", "center" or right"
- font (optional) -- a triple (fontname, fontsize, fonttype)
-
- Write text - the string representation of arg - at the current
- turtle position according to align ("left", "center" or right")
- and with the given font.
- If move is True, the pen is moved to the bottom-right corner
- of the text. By default, move is False.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.write(\'Home = \', True, align="center")
- >>> turtle.write((0,0), True)
- '''
- if self.undobuffer:
- self.undobuffer.push([
- 'seq'])
- self.undobuffer.cumulate = True
-
- end = self._write(str(arg), align.lower(), font)
- if move:
- (x, y) = self.pos()
- self.setpos(end, y)
-
- if self.undobuffer:
- self.undobuffer.cumulate = False
-
-
-
- def begin_poly(self):
- '''Start recording the vertices of a polygon.
-
- No argument.
-
- Start recording the vertices of a polygon. Current turtle position
- is first point of polygon.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.begin_poly()
- '''
- self._poly = [
- self._position]
- self._creatingPoly = True
-
-
- def end_poly(self):
- '''Stop recording the vertices of a polygon.
-
- No argument.
-
- Stop recording the vertices of a polygon. Current turtle position is
- last point of polygon. This will be connected with the first point.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.end_poly()
- '''
- self._creatingPoly = False
-
-
- def get_poly(self):
- '''Return the lastly recorded polygon.
-
- No argument.
-
- Example (for a Turtle instance named turtle):
- >>> p = turtle.get_poly()
- >>> turtle.register_shape("myFavouriteShape", p)
- '''
- if self._poly is not None:
- return tuple(self._poly)
-
-
- def getscreen(self):
- '''Return the TurtleScreen object, the turtle is drawing on.
-
- No argument.
-
- Return the TurtleScreen object, the turtle is drawing on.
- So TurtleScreen-methods can be called for that object.
-
- Example (for a Turtle instance named turtle):
- >>> ts = turtle.getscreen()
- >>> ts
- <turtle.TurtleScreen object at 0x0106B770>
- >>> ts.bgcolor("pink")
- '''
- return self.screen
-
-
- def getturtle(self):
- """Return the Turtleobject itself.
-
- No argument.
-
- Only reasonable use: as a function to return the 'anonymous turtle':
-
- Example:
- >>> pet = getturtle()
- >>> pet.fd(50)
- >>> pet
- <turtle.Turtle object at 0x0187D810>
- >>> turtles()
- [<turtle.Turtle object at 0x0187D810>]
- """
- return self
-
- getpen = getturtle
-
- def window_width(self):
- ''' Returns the width of the turtle window.
-
- No argument.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.window_width()
- 640
- '''
- return self.screen._window_size()[0]
-
-
- def window_height(self):
- ''' Return the height of the turtle window.
-
- No argument.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.window_height()
- 480
- '''
- return self.screen._window_size()[1]
-
-
- def _delay(self, delay = None):
- '''Set delay value which determines speed of turtle animation.
- '''
- return self.screen.delay(delay)
-
-
- def onclick(self, fun, btn = 1, add = None):
- '''Bind fun to mouse-click event on this turtle on canvas.
-
- Arguments:
- fun -- a function with two arguments, to which will be assigned
- the coordinates of the clicked point on the canvas.
- num -- number of the mouse-button defaults to 1 (left mouse button).
- add -- True or False. If True, new binding will be added, otherwise
- it will replace a former binding.
-
- Example for the anonymous turtle, i. e. the procedural way:
-
- >>> def turn(x, y):
- left(360)
-
- >>> onclick(turn) # Now clicking into the turtle will turn it.
- >>> onclick(None) # event-binding will be removed
- '''
- self.screen._onclick(self.turtle._item, fun, btn, add)
- self._update()
-
-
- def onrelease(self, fun, btn = 1, add = None):
- '''Bind fun to mouse-button-release event on this turtle on canvas.
-
- Arguments:
- fun -- a function with two arguments, to which will be assigned
- the coordinates of the clicked point on the canvas.
- num -- number of the mouse-button defaults to 1 (left mouse button).
-
- Example (for a MyTurtle instance named joe):
- >>> class MyTurtle(Turtle):
- def glow(self,x,y):
- self.fillcolor("red")
- def unglow(self,x,y):
- self.fillcolor("")
-
- >>> joe = MyTurtle()
- >>> joe.onclick(joe.glow)
- >>> joe.onrelease(joe.unglow)
- ### clicking on joe turns fillcolor red,
- ### unclicking turns it to transparent.
- '''
- self.screen._onrelease(self.turtle._item, fun, btn, add)
- self._update()
-
-
- def ondrag(self, fun, btn = 1, add = None):
- '''Bind fun to mouse-move event on this turtle on canvas.
-
- Arguments:
- fun -- a function with two arguments, to which will be assigned
- the coordinates of the clicked point on the canvas.
- num -- number of the mouse-button defaults to 1 (left mouse button).
-
- Every sequence of mouse-move-events on a turtle is preceded by a
- mouse-click event on that turtle.
-
- Example (for a Turtle instance named turtle):
- >>> turtle.ondrag(turtle.goto)
-
- ### Subsequently clicking and dragging a Turtle will
- ### move it across the screen thereby producing handdrawings
- ### (if pen is down).
- '''
- self.screen._ondrag(self.turtle._item, fun, btn, add)
-
-
- def _undo(self, action, data):
- '''Does the main part of the work for undo()
- '''
- if self.undobuffer is None:
- return None
- if action == 'rot':
- (angle, degPAU) = data
- self._rotate(-angle * degPAU / self._degreesPerAU)
- dummy = self.undobuffer.pop()
- elif action == 'stamp':
- stitem = data[0]
- self.clearstamp(stitem)
- elif action == 'go':
- self._undogoto(data)
- elif action in ('wri', 'dot'):
- item = data[0]
- self.screen._delete(item)
- self.items.remove(item)
- elif action == 'dofill':
- item = data[0]
- self.screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), fill = '', outline = '')
- elif action == 'beginfill':
- item = data[0]
- self._fillitem = None
- self._fillpath = None
- self.screen._delete(item)
- self.items.remove(item)
- elif action == 'pen':
- TPen.pen(self, data[0])
- self.undobuffer.pop()
-
-
-
- def undo(self):
- '''undo (repeatedly) the last turtle action.
-
- No argument.
-
- undo (repeatedly) the last turtle action.
- Number of available undo actions is determined by the size of
- the undobuffer.
-
- Example (for a Turtle instance named turtle):
- >>> for i in range(4):
- turtle.fd(50); turtle.lt(80)
-
- >>> for i in range(8):
- turtle.undo()
- '''
- if self.undobuffer is None:
- return None
- item = self.undobuffer.pop()
- action = item[0]
- data = item[1:]
-
- turtlesize = shapesize
-
- RawPen = RawTurtle
-
- def Screen():
- '''Return the singleton screen object.
- If none exists at the moment, create a new one and return it,
- else return the existing one.'''
- if Turtle._screen is None:
- Turtle._screen = _Screen()
-
- return Turtle._screen
-
-
- class _Screen(TurtleScreen):
- _root = None
- _canvas = None
- _title = _CFG['title']
-
- def __init__(self):
- if _Screen._root is None:
- _Screen._root = self._root = _Root()
- self._root.title(_Screen._title)
- self._root.ondestroy(self._destroy)
-
- if _Screen._canvas is None:
- width = _CFG['width']
- height = _CFG['height']
- canvwidth = _CFG['canvwidth']
- canvheight = _CFG['canvheight']
- leftright = _CFG['leftright']
- topbottom = _CFG['topbottom']
- self._root.setupcanvas(width, height, canvwidth, canvheight)
- _Screen._canvas = self._root._getcanvas()
- TurtleScreen.__init__(self, _Screen._canvas)
- self.setup(width, height, leftright, topbottom)
-
-
-
- def setup(self, width = _CFG['width'], height = _CFG['height'], startx = _CFG['leftright'], starty = _CFG['topbottom']):
- ''' Set the size and position of the main window.
-
- Arguments:
- width: as integer a size in pixels, as float a fraction of the screen.
- Default is 50% of screen.
- height: as integer the height in pixels, as float a fraction of the
- screen. Default is 75% of screen.
- startx: if positive, starting position in pixels from the left
- edge of the screen, if negative from the right edge
- Default, startx=None is to center window horizontally.
- starty: if positive, starting position in pixels from the top
- edge of the screen, if negative from the bottom edge
- Default, starty=None is to center window vertically.
-
- Examples (for a Screen instance named screen):
- >>> screen.setup (width=200, height=200, startx=0, starty=0)
-
- sets window to 200x200 pixels, in upper left of screen
-
- >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
-
- sets window to 75% of screen by 50% of screen and centers
- '''
- if not hasattr(self._root, 'set_geometry'):
- return None
- sw = self._root.win_width()
- sh = self._root.win_height()
- if isinstance(width, float):
- if width <= width:
- pass
- elif width <= 1:
- width = sw * width
-
- if startx is None:
- startx = (sw - width) / 2
-
- if isinstance(height, float):
- if height <= height:
- pass
- elif height <= 1:
- height = sh * height
-
- if starty is None:
- starty = (sh - height) / 2
-
- self._root.set_geometry(width, height, startx, starty)
- self.update()
-
-
- def title(self, titlestring):
- '''Set title of turtle-window
-
- Argument:
- titlestring -- a string, to appear in the titlebar of the
- turtle graphics window.
-
- This is a method of Screen-class. Not available for TurtleScreen-
- objects.
-
- Example (for a Screen instance named screen):
- >>> screen.title("Welcome to the turtle-zoo!")
- '''
- if _Screen._root is not None:
- _Screen._root.title(titlestring)
-
- _Screen._title = titlestring
-
-
- def _destroy(self):
- root = self._root
- if root is _Screen._root:
- Turtle._pen = None
- Turtle._screen = None
- _Screen._root = None
- _Screen._canvas = None
-
- TurtleScreen._RUNNING = True
- root.destroy()
-
-
- def bye(self):
- '''Shut the turtlegraphics window.
-
- Example (for a TurtleScreen instance named screen):
- >>> screen.bye()
- '''
- self._destroy()
-
-
- def exitonclick(self):
- '''Go into mainloop until the mouse is clicked.
-
- No arguments.
-
- Bind bye() method to mouseclick on TurtleScreen.
- If "using_IDLE" - value in configuration dictionary is False
- (default value), enter mainloop.
- If IDLE with -n switch (no subprocess) is used, this value should be
- set to True in turtle.cfg. In this case IDLE\'s mainloop
- is active also for the client script.
-
- This is a method of the Screen-class and not available for
- TurtleScreen instances.
-
- Example (for a Screen instance named screen):
- >>> screen.exitonclick()
-
- '''
-
- def exitGracefully(x, y):
- '''Screen.bye() with two dummy-parameters'''
- self.bye()
-
- self.onclick(exitGracefully)
- if _CFG['using_IDLE']:
- return None
-
- try:
- mainloop()
- except AttributeError:
- _CFG['using_IDLE']
- _CFG['using_IDLE']
- (None,)
- exit(0)
- except:
- _CFG['using_IDLE']
-
-
-
-
- class Turtle(RawTurtle):
- '''RawTurtle auto-crating (scrolled) canvas.
-
- When a Turtle object is created or a function derived from some
- Turtle method is called a TurtleScreen object is automatically created.
- '''
- _pen = None
- _screen = None
-
- def __init__(self, shape = _CFG['shape'], undobuffersize = _CFG['undobuffersize'], visible = _CFG['visible']):
- if Turtle._screen is None:
- Turtle._screen = Screen()
-
- RawTurtle.__init__(self, Turtle._screen, shape = shape, undobuffersize = undobuffersize, visible = visible)
-
-
- Pen = Turtle
-
- def _getpen():
- """Create the 'anonymous' turtle if not already present."""
- if Turtle._pen is None:
- Turtle._pen = Turtle()
-
- return Turtle._pen
-
-
- def _getscreen():
- '''Create a TurtleScreen if not already present.'''
- if Turtle._screen is None:
- Turtle._screen = Screen()
-
- return Turtle._screen
-
-
- def write_docstringdict(filename = 'turtle_docstringdict'):
- '''Create and write docstring-dictionary to file.
-
- Optional argument:
- filename -- a string, used as filename
- default value is turtle_docstringdict
-
- Has to be called explicitely, (not used by the turtle-graphics classes)
- The docstring dictionary will be written to the Python script <filname>.py
- It is intended to serve as a template for translation of the docstrings
- into different languages.
- '''
- docsdict = { }
- for methodname in _tg_screen_functions:
- key = '_Screen.' + methodname
- docsdict[key] = eval(key).__doc__
-
- for methodname in _tg_turtle_functions:
- key = 'Turtle.' + methodname
- docsdict[key] = eval(key).__doc__
-
- f = open('%s.py' % filename, 'w')
- keys = [](_[1])
- f.write('docsdict = {\n\n')
- for key in keys[:-1]:
- f.write('%s :\n' % repr(key))
- f.write(' """%s\n""",\n\n' % docsdict[key])
-
- key = keys[-1]
- f.write('%s :\n' % repr(key))
- f.write(' """%s\n"""\n\n' % docsdict[key])
- f.write('}\n')
- f.close()
-
-
- def read_docstrings(lang):
- '''Read in docstrings from lang-specific docstring dictionary.
-
- Transfer docstrings, translated to lang, from a dictionary-file
- to the methods of classes Screen and Turtle and - in revised form -
- to the corresponding functions.
- '''
- modname = 'turtle_docstringdict_%(language)s' % {
- 'language': lang.lower() }
- module = __import__(modname)
- docsdict = module.docsdict
- for key in docsdict:
-
- try:
- eval(key).im_func.__doc__ = docsdict[key]
- continue
- print 'Bad docstring-entry: %s' % key
- continue
-
-
-
- _LANGUAGE = _CFG['language']
-
- try:
- if _LANGUAGE != 'english':
- read_docstrings(_LANGUAGE)
- except ImportError:
- print 'Cannot find docsdict for', _LANGUAGE
- except:
- print 'Unknown Error when trying to import %s-docstring-dictionary' % _LANGUAGE
-
-
- def getmethparlist(ob):
- '''Get strings describing the arguments for the given object'''
- argText1 = argText2 = ''
- if type(ob) == types.MethodType:
- fob = ob.im_func
- argOffset = 1
- else:
- fob = ob
- argOffset = 0
- if type(fob) in [
- types.FunctionType,
- types.LambdaType]:
-
- try:
- counter = fob.func_code.co_argcount
- items2 = list(fob.func_code.co_varnames[argOffset:counter])
- realArgs = fob.func_code.co_varnames[argOffset:counter]
- if not fob.func_defaults:
- pass
- defaults = []
- defaults = list(map((lambda name: '=%s' % repr(name)), defaults))
- defaults = [
- ''] * (len(realArgs) - len(defaults)) + defaults
- items1 = map((lambda arg, dflt: arg + dflt), realArgs, defaults)
- if fob.func_code.co_flags & 4:
- items1.append('*' + fob.func_code.co_varnames[counter])
- items2.append('*' + fob.func_code.co_varnames[counter])
- counter += 1
-
- if fob.func_code.co_flags & 8:
- items1.append('**' + fob.func_code.co_varnames[counter])
- items2.append('**' + fob.func_code.co_varnames[counter])
-
- argText1 = ', '.join(items1)
- argText1 = '(%s)' % argText1
- argText2 = ', '.join(items2)
- argText2 = '(%s)' % argText2
-
-
- return (argText1, argText2)
-
-
- def _turtle_docrevise(docstr):
- '''To reduce docstrings from RawTurtle class for functions
- '''
- import re
- if docstr is None:
- return None
- turtlename = _CFG['exampleturtle']
- newdocstr = docstr.replace('%s.' % turtlename, '')
- parexp = re.compile(' \\(.+ %s\\):' % turtlename)
- newdocstr = parexp.sub(':', newdocstr)
- return newdocstr
-
-
- def _screen_docrevise(docstr):
- '''To reduce docstrings from TurtleScreen class for functions
- '''
- import re
- if docstr is None:
- return None
- screenname = _CFG['examplescreen']
- newdocstr = docstr.replace('%s.' % screenname, '')
- parexp = re.compile(' \\(.+ %s\\):' % screenname)
- newdocstr = parexp.sub(':', newdocstr)
- return newdocstr
-
- for methodname in _tg_screen_functions:
- (pl1, pl2) = getmethparlist(eval('_Screen.' + methodname))
- if pl1 == '':
- print '>>>>>>', pl1, pl2
- continue
-
- defstr = 'def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s' % {
- 'key': methodname,
- 'pl1': pl1,
- 'pl2': pl2 }
- exec defstr
- eval(methodname).__doc__ = _screen_docrevise(eval('_Screen.' + methodname).__doc__)
-
- for methodname in _tg_turtle_functions:
- (pl1, pl2) = getmethparlist(eval('Turtle.' + methodname))
- if pl1 == '':
- print '>>>>>>', pl1, pl2
- continue
-
- defstr = 'def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s' % {
- 'key': methodname,
- 'pl1': pl1,
- 'pl2': pl2 }
- exec defstr
- eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.' + methodname).__doc__)
-
- done = mainloop = TK.mainloop
- del pl1
- del pl2
- del defstr
- if __name__ == '__main__':
-
- def switchpen():
- if isdown():
- pu()
- else:
- pd()
-
-
- def demo1():
- '''Demo of old turtle.py - module'''
- reset()
- tracer(True)
- up()
- backward(100)
- down()
- width(3)
- for i in range(3):
- if i == 2:
- fill(1)
-
- for _ in range(4):
- forward(20)
- left(90)
-
- if i == 2:
- color('maroon')
- fill(0)
-
- up()
- forward(30)
- down()
-
- width(1)
- color('black')
- tracer(False)
- up()
- right(90)
- forward(100)
- right(90)
- forward(100)
- right(180)
- down()
- write('startstart', 1)
- write('start', 1)
- color('red')
- for i in range(5):
- forward(20)
- left(90)
- forward(20)
- right(90)
-
- tracer(True)
- fill(1)
- for i in range(5):
- forward(20)
- left(90)
- forward(20)
- right(90)
-
- fill(0)
-
-
- def demo2():
- '''Demo of some new features.'''
- speed(1)
- st()
- pensize(3)
- setheading(towards(0, 0))
- radius = distance(0, 0) / 2
- rt(90)
- for _ in range(18):
- switchpen()
- circle(radius, 10)
-
- write('wait a moment...')
- while undobufferentries():
- undo()
- reset()
- lt(90)
- colormode(255)
- laenge = 10
- pencolor('green')
- pensize(3)
- lt(180)
- for i in range(-2, 16):
- if i > 0:
- begin_fill()
- fillcolor(255 - 15 * i, 0, 15 * i)
-
- for _ in range(3):
- fd(laenge)
- lt(120)
-
- laenge += 10
- lt(15)
- speed((speed() + 1) % 12)
-
- end_fill()
- lt(120)
- pu()
- fd(70)
- rt(30)
- pd()
- color('red', 'yellow')
- speed(0)
- fill(1)
- for _ in range(4):
- circle(50, 90)
- rt(90)
- fd(30)
- rt(90)
-
- fill(0)
- lt(90)
- pu()
- fd(30)
- pd()
- shape('turtle')
- tri = getturtle()
- tri.resizemode('auto')
- turtle = Turtle()
- turtle.resizemode('auto')
- turtle.shape('turtle')
- turtle.reset()
- turtle.left(90)
- turtle.speed(0)
- turtle.up()
- turtle.goto(280, 40)
- turtle.lt(30)
- turtle.down()
- turtle.speed(6)
- turtle.color('blue', 'orange')
- turtle.pensize(2)
- tri.speed(6)
- setheading(towards(turtle))
- count = 1
- while tri.distance(turtle) > 4:
- turtle.fd(3.5)
- turtle.lt(0.6)
- tri.setheading(tri.towards(turtle))
- tri.fd(4)
- if count % 20 == 0:
- turtle.stamp()
- tri.stamp()
- switchpen()
-
- count += 1
- tri.write('CAUGHT! ', font = ('Arial', 16, 'bold'), align = 'right')
- tri.pencolor('black')
- tri.pencolor('red')
-
- def baba(xdummy, ydummy):
- clearscreen()
- bye()
-
- time.sleep(2)
- while undobufferentries():
- tri.undo()
- turtle.undo()
- tri.fd(50)
- tri.write(' Click me!', font = ('Courier', 12, 'bold'))
- tri.onclick(baba, 1)
-
- demo1()
- demo2()
- exitonclick()
-
-